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
This commit is contained in:
parent
b8ed3bc87f
commit
5a902f8f7a
6 changed files with 195 additions and 196 deletions
|
@ -126,8 +126,8 @@ bool Debugger::Cmd_GameState(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Debugger::Cmd_Info(int argc, const char **argv) {
|
bool Debugger::Cmd_Info(int argc, const char **argv) {
|
||||||
DebugPrintf("Version: %s\n", _vm->resource()->JASVersion());
|
DebugPrintf("Version: %s\n", _vm->resource()->getJASVersion());
|
||||||
DebugPrintf("Audio compression: %d\n", _vm->resource()->compression());
|
DebugPrintf("Audio compression: %d\n", _vm->resource()->getCompression());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -457,7 +457,7 @@ void Journal::drawConfigPanel() {
|
||||||
|
|
||||||
void Journal::drawInfoPanel() {
|
void Journal::drawInfoPanel() {
|
||||||
showBob(BOB_INFO_BOX, 72, 221, FRAME_INFO_BOX);
|
showBob(BOB_INFO_BOX, 72, 221, FRAME_INFO_BOX);
|
||||||
const char *ver = _vm->resource()->JASVersion();
|
const char *ver = _vm->resource()->getJASVersion();
|
||||||
switch (ver[0]) {
|
switch (ver[0]) {
|
||||||
case 'P':
|
case 'P':
|
||||||
_vm->display()->setTextCentered(132, "PC Hard Drive", false);
|
_vm->display()->setTextCentered(132, "PC Hard Drive", false);
|
||||||
|
|
|
@ -190,7 +190,7 @@ void Logic::initialise() {
|
||||||
_currentRoom = _objectData[_entryObj].room;
|
_currentRoom = _objectData[_entryObj].room;
|
||||||
_entryObj = 0;
|
_entryObj = 0;
|
||||||
|
|
||||||
if (memcmp(ptr, _vm->resource()->JASVersion(), 5) != 0) {
|
if (memcmp(ptr, _vm->resource()->getJASVersion(), 5) != 0) {
|
||||||
warning("Unexpected queen.jas file format");
|
warning("Unexpected queen.jas file format");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,39 +48,21 @@
|
||||||
|
|
||||||
#include "sound/mididrv.h"
|
#include "sound/mididrv.h"
|
||||||
|
|
||||||
/* Flight of the Amazon Queen */
|
static const PlainGameDescriptor queenGameDescriptor = {
|
||||||
static const PlainGameDescriptor queen_setting[] = {
|
"queen", "Flight of the Amazon Queen"
|
||||||
{ "queen", "Flight of the Amazon Queen" },
|
|
||||||
{ "queen", "Flight of the Amazon Queen (Demo)" },
|
|
||||||
{ "queen", "Flight of the Amazon Queen (Interview)" },
|
|
||||||
{ 0, 0 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GameList Engine_QUEEN_gameIDList() {
|
GameList Engine_QUEEN_gameIDList() {
|
||||||
GameList games;
|
GameList games;
|
||||||
games.push_back(queen_setting[0]);
|
games.push_back(queenGameDescriptor);
|
||||||
return games;
|
return games;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameDescriptor Engine_QUEEN_findGameID(const char *gameid) {
|
GameDescriptor Engine_QUEEN_findGameID(const char *gameid) {
|
||||||
if (0 == scumm_stricmp(gameid, queen_setting[0].gameid))
|
if (0 == scumm_stricmp(gameid, queenGameDescriptor.gameid)) {
|
||||||
return queen_setting[0];
|
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];
|
return GameDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
DetectedGameList Engine_QUEEN_detectGames(const FSList &fslist) {
|
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
|
// Iterate over all files in the given directory
|
||||||
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
||||||
if (!file->isDirectory()) {
|
if (file->isDirectory()) {
|
||||||
const char *fileName = file->name().c_str();
|
continue;
|
||||||
|
}
|
||||||
if (0 == scumm_stricmp("queen.1", fileName) || 0 == scumm_stricmp("queen.1c", fileName)) {
|
if (file->name().equalsIgnoreCase("queen.1") || file->name().equalsIgnoreCase("queen.1c")) {
|
||||||
Common::File dataFile;
|
Common::File dataFile;
|
||||||
dataFile.open(*file);
|
if (!dataFile.open(*file)) {
|
||||||
assert(dataFile.isOpen());
|
continue;
|
||||||
|
}
|
||||||
if (0 == scumm_stricmp("queen.1", fileName)) { //an unmodified file
|
Queen::DetectedGameVersion version;
|
||||||
detectedGames.push_back(determineTarget(dataFile.size()));
|
if (Queen::Resource::detectVersion(&version, &dataFile)) {
|
||||||
} else if (0 == scumm_stricmp("queen.1c", fileName)) { //oh joy, it's a rebuilt file
|
DetectedGame dg(queenGameDescriptor.gameid, queenGameDescriptor.description, version.language, Common::kPlatformPC);
|
||||||
char header[9];
|
if (version.features & Queen::GF_DEMO) {
|
||||||
dataFile.read(header, 9);
|
dg.updateDesc("Demo");
|
||||||
if (0 == scumm_strnicmp("QTBL", header, 4)) { //check validity
|
} else if (version.features & Queen::GF_INTERVIEW) {
|
||||||
uint8 version = 0; //default to full/normal version
|
dg.updateDesc("Interview");
|
||||||
|
} else if (version.features & Queen::GF_FLOPPY) {
|
||||||
if (0 == scumm_strnicmp("PE100", header + 4, 5)) //One of the 2 regular demos
|
dg.updateDesc("Floppy");
|
||||||
version = 1;
|
} else if (version.features & Queen::GF_TALKIE) {
|
||||||
if (0 == scumm_strnicmp("PEint", header + 4, 5)) //Interview demo
|
dg.updateDesc("Talkie");
|
||||||
version = 2;
|
|
||||||
|
|
||||||
detectedGames.push_back(queen_setting[version]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
detectedGames.push_back(dg);
|
||||||
dataFile.close();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,7 +398,7 @@ int QueenEngine::init() {
|
||||||
_music = new Music(driver, this);
|
_music = new Music(driver, this);
|
||||||
_music->hasNativeMT32(native_mt32);
|
_music->hasNativeMT32(native_mt32);
|
||||||
|
|
||||||
_sound = Sound::giveSound(_mixer, this, _resource->compression());
|
_sound = Sound::giveSound(_mixer, this, _resource->getCompression());
|
||||||
_walk = new Walk(this);
|
_walk = new Walk(this);
|
||||||
//_talkspeedScale = (MAX_TEXT_SPEED - MIN_TEXT_SPEED) / 255.0;
|
//_talkspeedScale = (MAX_TEXT_SPEED - MIN_TEXT_SPEED) / 255.0;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common/stdafx.h"
|
#include "common/stdafx.h"
|
||||||
|
#include "common/endian.h"
|
||||||
#include "common/config-manager.h"
|
#include "common/config-manager.h"
|
||||||
#include "queen/resource.h"
|
#include "queen/resource.h"
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ static ResourceEntry *_resourceTablePEM10;
|
||||||
|
|
||||||
const char *Resource::_tableFilename = "queen.tbl";
|
const char *Resource::_tableFilename = "queen.tbl";
|
||||||
|
|
||||||
const GameVersion Resource::_gameVersions[] = {
|
const RetailGameVersion Resource::_gameVersions[] = {
|
||||||
{ "PEM10", 0x00000008, 22677657 },
|
{ "PEM10", 0x00000008, 22677657 },
|
||||||
{ "CEM10", 0x0000584E, 190787021 },
|
{ "CEM10", 0x0000584E, 190787021 },
|
||||||
{ "PFM10", 0x0002CD93, 22157304 },
|
{ "PFM10", 0x0002CD93, 22157304 },
|
||||||
|
@ -56,16 +57,29 @@ static int compareResourceEntry(const void *a, const void *b) {
|
||||||
|
|
||||||
Resource::Resource()
|
Resource::Resource()
|
||||||
: _resourceEntries(0), _resourceTable(NULL) {
|
: _resourceEntries(0), _resourceTable(NULL) {
|
||||||
_resourceFile = new Common::File();
|
memset(&_version, 0, sizeof(_version));
|
||||||
if (!findCompressedVersion() && !findNormalVersion())
|
|
||||||
error("Could not open resource file '%s'", "queen.1");
|
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();
|
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() {
|
Resource::~Resource() {
|
||||||
_resourceFile->close();
|
_resourceFile.close();
|
||||||
delete _resourceFile;
|
|
||||||
|
|
||||||
if (_resourceTable != _resourceTablePEM10)
|
if (_resourceTable != _resourceTablePEM10)
|
||||||
delete[] _resourceTable;
|
delete[] _resourceTable;
|
||||||
|
@ -74,22 +88,17 @@ Resource::~Resource() {
|
||||||
ResourceEntry *Resource::resourceEntry(const char *filename) const {
|
ResourceEntry *Resource::resourceEntry(const char *filename) const {
|
||||||
assert(filename[0] && strlen(filename) < 14);
|
assert(filename[0] && strlen(filename) < 14);
|
||||||
|
|
||||||
char entryName[14];
|
Common::String entryName(filename);
|
||||||
char *ptr = entryName;
|
entryName.toUppercase();
|
||||||
|
|
||||||
strcpy(entryName, filename);
|
|
||||||
do
|
|
||||||
*ptr = toupper(*ptr);
|
|
||||||
while (*ptr++);
|
|
||||||
|
|
||||||
ResourceEntry *re = NULL;
|
ResourceEntry *re = NULL;
|
||||||
#ifndef PALMOS_MODE
|
#ifndef PALMOS_MODE
|
||||||
re = (ResourceEntry *)bsearch(entryName, _resourceTable, _resourceEntries, sizeof(ResourceEntry), compareResourceEntry);
|
re = (ResourceEntry *)bsearch(entryName.c_str(), _resourceTable, _resourceEntries, sizeof(ResourceEntry), compareResourceEntry);
|
||||||
#else
|
#else
|
||||||
// PALMOS FIXME (?) : still doesn't work for me (????) use this instead
|
// PALMOS FIXME (?) : still doesn't work for me (????) use this instead
|
||||||
uint32 cur = 0;
|
uint32 cur = 0;
|
||||||
do {
|
do {
|
||||||
if (!strcmp(entryName, _resourceTable[cur].filename)) {
|
if (!strcmp(entryName.c_str(), _resourceTable[cur].filename)) {
|
||||||
re = &_resourceTable[cur];
|
re = &_resourceTable[cur];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -113,44 +122,78 @@ uint8 *Resource::loadFile(const char *filename, uint32 skipBytes, uint32 *size,
|
||||||
dstBuf = new byte[sz];
|
dstBuf = new byte[sz];
|
||||||
}
|
}
|
||||||
|
|
||||||
_resourceFile->seek(re->offset + skipBytes);
|
_resourceFile.seek(re->offset + skipBytes);
|
||||||
_resourceFile->read(dstBuf, sz);
|
_resourceFile.read(dstBuf, sz);
|
||||||
return dstBuf;
|
return dstBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resource::findNormalVersion() {
|
bool Resource::detectVersion(DetectedGameVersion *ver, Common::File *f) {
|
||||||
_resourceFile->open("queen.1");
|
memset(ver, 0, sizeof(DetectedGameVersion));
|
||||||
if (!_resourceFile->isOpen()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_compression = COMPRESSION_NONE;
|
char versionStr[6];
|
||||||
|
if (f->readUint32BE() == MKID_BE('QTBL')) {
|
||||||
// detect game version based on resource file size ; we try to
|
f->read(versionStr, 6);
|
||||||
// verify that it is indeed the version we think it is later on
|
f->skip(2);
|
||||||
const GameVersion *gameVersion = detectGameVersion(_resourceFile->size());
|
ver->compression = f->readByte();
|
||||||
if (gameVersion == NULL)
|
ver->features = GF_REBUILT;
|
||||||
error("Unknown/unsupported FOTAQ version");
|
ver->tableOffset = 0;
|
||||||
|
} else {
|
||||||
strcpy(_versionString, gameVersion->versionString);
|
const RetailGameVersion *gameVersion = detectGameVersionFromSize(f->size());
|
||||||
if (!readTableFile(gameVersion)) {
|
if (gameVersion == NULL) {
|
||||||
// check if it is the english floppy version, for which we have a hardcoded version of the table
|
warning("Unknown/unsupported FOTAQ version");
|
||||||
if (!strcmp(gameVersion->versionString, _gameVersions[VER_ENG_FLOPPY].versionString)) {
|
return false;
|
||||||
_resourceEntries = 1076;
|
|
||||||
_resourceTable = _resourceTablePEM10;
|
|
||||||
} else {
|
|
||||||
error("Could not find tablefile '%s'", _tableFilename);
|
|
||||||
}
|
}
|
||||||
|
strcpy(versionStr, gameVersion->str);
|
||||||
|
ver->compression = COMPRESSION_NONE;
|
||||||
|
ver->features = 0;
|
||||||
|
ver->tableOffset = gameVersion->tableOffset;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Resource::findCompressedVersion() {
|
switch (versionStr[1]) {
|
||||||
_resourceFile->open("queen.1c");
|
case 'E':
|
||||||
if (!_resourceFile->isOpen()) {
|
if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS) {
|
||||||
return false;
|
ver->language = Common::RU_RUS;
|
||||||
|
} else {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
readTableCompResource();
|
|
||||||
|
switch (versionStr[0]) {
|
||||||
|
case 'P':
|
||||||
|
ver->features |= GF_FLOPPY;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
ver->features |= GF_TALKIE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,58 +207,32 @@ void Resource::checkJASVersion() {
|
||||||
offset += JAS_VERSION_OFFSET_INTV;
|
offset += JAS_VERSION_OFFSET_INTV;
|
||||||
else
|
else
|
||||||
offset += JAS_VERSION_OFFSET_PC;
|
offset += JAS_VERSION_OFFSET_PC;
|
||||||
_resourceFile->seek(offset);
|
_resourceFile.seek(offset);
|
||||||
|
|
||||||
char versionStr[6];
|
char versionStr[6];
|
||||||
_resourceFile->read(versionStr, 6);
|
_resourceFile.read(versionStr, 6);
|
||||||
if (strcmp(_versionString, versionStr))
|
if (strcmp(_version.str, versionStr))
|
||||||
error("Verifying game version failed! (expected: '%s', found: '%s')", _versionString, versionStr);
|
error("Verifying game version failed! (expected: '%s', found: '%s')", _version.str, versionStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Language Resource::getLanguage() const {
|
void Resource::readTableFile(uint32 offset) {
|
||||||
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) {
|
|
||||||
Common::File tableFile;
|
Common::File tableFile;
|
||||||
tableFile.open(_tableFilename);
|
tableFile.open(_tableFilename);
|
||||||
if (tableFile.isOpen() && tableFile.readUint32BE() == 'QTBL') {
|
if (tableFile.isOpen() && tableFile.readUint32BE() == MKID_BE('QTBL')) {
|
||||||
if (tableFile.readUint32BE() != CURRENT_TBL_VERSION)
|
if (tableFile.readUint32BE() != CURRENT_TBL_VERSION) {
|
||||||
warning("Incorrect version of queen.tbl, please update it");
|
warning("Incorrect version of queen.tbl, please update it");
|
||||||
tableFile.seek(gameVersion->tableOffset);
|
}
|
||||||
|
tableFile.seek(offset);
|
||||||
readTableEntries(&tableFile);
|
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) {
|
void Resource::readTableEntries(Common::File *file) {
|
||||||
|
@ -231,11 +248,10 @@ void Resource::readTableEntries(Common::File *file) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const GameVersion *Resource::detectGameVersion(uint32 size) const {
|
const RetailGameVersion *Resource::detectGameVersionFromSize(uint32 size) {
|
||||||
const GameVersion *pgv = _gameVersions;
|
for (int i = 0; i < VER_COUNT; ++i) {
|
||||||
for (int i = 0; i < VER_COUNT; ++i, ++pgv) {
|
if (_gameVersions[i].dataFileSize == size) {
|
||||||
if (pgv->dataFileSize == size) {
|
return &_gameVersions[i];
|
||||||
return pgv;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -249,8 +265,8 @@ Common::File *Resource::giveCompressedSound(const char *filename, uint32 *size)
|
||||||
if (size != NULL) {
|
if (size != NULL) {
|
||||||
*size = re->size;
|
*size = re->size;
|
||||||
}
|
}
|
||||||
_resourceFile->seek(re->offset);
|
_resourceFile.seek(re->offset);
|
||||||
f = _resourceFile;
|
f = &_resourceFile;
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,28 @@
|
||||||
|
|
||||||
namespace Queen {
|
namespace Queen {
|
||||||
|
|
||||||
|
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 RetailGameVersion {
|
||||||
|
char str[6];
|
||||||
|
uint32 tableOffset;
|
||||||
|
uint32 dataFileSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DetectedGameVersion {
|
||||||
|
Common::Language language;
|
||||||
|
uint8 features;
|
||||||
|
uint8 compression;
|
||||||
|
char str[6];
|
||||||
|
uint32 tableOffset;
|
||||||
|
};
|
||||||
|
|
||||||
struct ResourceEntry {
|
struct ResourceEntry {
|
||||||
char filename[13];
|
char filename[13];
|
||||||
uint8 bundle;
|
uint8 bundle;
|
||||||
|
@ -36,26 +58,6 @@ struct ResourceEntry {
|
||||||
uint32 size;
|
uint32 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GameVersion {
|
|
||||||
char versionString[6];
|
|
||||||
uint32 tableOffset;
|
|
||||||
uint32 dataFileSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LineReader {
|
|
||||||
public:
|
|
||||||
|
|
||||||
LineReader(char *buffer, uint32 bufsize);
|
|
||||||
~LineReader();
|
|
||||||
char *nextLine();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
char *_buffer;
|
|
||||||
uint32 _bufSize;
|
|
||||||
int _current;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Resource {
|
class Resource {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -71,19 +73,22 @@ public:
|
||||||
//! returns a reference to a sound file
|
//! returns a reference to a sound file
|
||||||
Common::File *giveCompressedSound(const char *filename, uint32 *size);
|
Common::File *giveCompressedSound(const char *filename, uint32 *size);
|
||||||
|
|
||||||
bool isDemo() const { return !strcmp(_versionString, "PE100"); }
|
bool isDemo() const { return _version.features & GF_DEMO; }
|
||||||
bool isInterview() const { return !strcmp(_versionString, "PEint"); }
|
bool isInterview() const { return _version.features & GF_INTERVIEW; }
|
||||||
bool isFloppy() const { return _versionString[0] == 'P'; }
|
bool isFloppy() const { return _version.features & GF_FLOPPY; }
|
||||||
bool isCD() const { return _versionString[0] == 'C'; }
|
bool isCD() const { return _version.features & GF_TALKIE; }
|
||||||
|
|
||||||
//! returns compression type for audio files
|
//! 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)
|
//! 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
|
//! returns the language of the game
|
||||||
Common::Language getLanguage() const;
|
Common::Language getLanguage() const { return _version.language; }
|
||||||
|
|
||||||
|
//! detect game version
|
||||||
|
static bool detectVersion(DetectedGameVersion *ver, Common::File *f);
|
||||||
|
|
||||||
enum Version {
|
enum Version {
|
||||||
VER_ENG_FLOPPY = 0,
|
VER_ENG_FLOPPY = 0,
|
||||||
|
@ -115,25 +120,15 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Common::File *_resourceFile;
|
Common::File _resourceFile;
|
||||||
|
|
||||||
//! compression type for audio files
|
DetectedGameVersion _version;
|
||||||
uint8 _compression;
|
|
||||||
|
|
||||||
//! JAS version string of the game
|
|
||||||
char _versionString[6];
|
|
||||||
|
|
||||||
//! number of entries in resource table
|
//! number of entries in resource table
|
||||||
uint32 _resourceEntries;
|
uint32 _resourceEntries;
|
||||||
|
|
||||||
ResourceEntry *_resourceTable;
|
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
|
//! verify the version of the selected game
|
||||||
void checkJASVersion();
|
void checkJASVersion();
|
||||||
|
|
||||||
|
@ -141,22 +136,19 @@ protected:
|
||||||
ResourceEntry *resourceEntry(const char *filename) const;
|
ResourceEntry *resourceEntry(const char *filename) const;
|
||||||
|
|
||||||
//! extarct the resource table for the specified game version
|
//! 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
|
//! read the resource table from the specified file
|
||||||
void readTableEntries(Common::File *file);
|
void readTableEntries(Common::File *file);
|
||||||
|
|
||||||
//! detect game version based on queen.1 datafile size
|
//! 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)
|
//! resource table filename (queen.tbl)
|
||||||
static const char *_tableFilename;
|
static const char *_tableFilename;
|
||||||
|
|
||||||
//! known FOTAQ versions
|
//! known FOTAQ versions
|
||||||
static const GameVersion _gameVersions[];
|
static const RetailGameVersion _gameVersions[];
|
||||||
|
|
||||||
#ifndef PALMOS_68K
|
#ifndef PALMOS_68K
|
||||||
//! resource table for english floppy version
|
//! resource table for english floppy version
|
||||||
|
@ -164,6 +156,20 @@ protected:
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LineReader {
|
||||||
|
public:
|
||||||
|
|
||||||
|
LineReader(char *buffer, uint32 bufsize);
|
||||||
|
~LineReader();
|
||||||
|
char *nextLine();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
char *_buffer;
|
||||||
|
uint32 _bufSize;
|
||||||
|
int _current;
|
||||||
|
};
|
||||||
|
|
||||||
} // End of namespace Queen
|
} // End of namespace Queen
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue