diff options
-rw-r--r-- | engines/kyra/animator.cpp | 4 | ||||
-rw-r--r-- | engines/kyra/gui.cpp | 18 | ||||
-rw-r--r-- | engines/kyra/items.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/kyra.cpp | 10 | ||||
-rw-r--r-- | engines/kyra/kyra.h | 28 | ||||
-rw-r--r-- | engines/kyra/kyra2.h | 2 | ||||
-rw-r--r-- | engines/kyra/kyra3.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/plugin.cpp | 143 | ||||
-rw-r--r-- | engines/kyra/resource.cpp | 8 | ||||
-rw-r--r-- | engines/kyra/saveload.cpp | 20 | ||||
-rw-r--r-- | engines/kyra/scene.cpp | 4 | ||||
-rw-r--r-- | engines/kyra/screen.cpp | 24 | ||||
-rw-r--r-- | engines/kyra/script_v1.cpp | 14 | ||||
-rw-r--r-- | engines/kyra/seqplayer.cpp | 20 | ||||
-rw-r--r-- | engines/kyra/sequences_v1.cpp | 24 | ||||
-rw-r--r-- | engines/kyra/sound.cpp | 4 | ||||
-rw-r--r-- | engines/kyra/staticres.cpp | 66 | ||||
-rw-r--r-- | engines/kyra/wsamovie.cpp | 2 |
18 files changed, 209 insertions, 186 deletions
diff --git a/engines/kyra/animator.cpp b/engines/kyra/animator.cpp index df8aa8284c..a11e56d65e 100644 --- a/engines/kyra/animator.cpp +++ b/engines/kyra/animator.cpp @@ -598,14 +598,14 @@ void ScreenAnimator::makeBrandonFaceMouse() { int16 ScreenAnimator::fetchAnimWidth(const uint8 *shape, int16 mult) { debugC(9, kDebugLevelAnimator, "ScreenAnimator::fetchAnimWidth(%p, %d)", (const void *)shape, mult); - if (_vm->features() & GF_TALKIE) + if (_vm->gameFlags().useAltShapeHeader) shape += 2; return (((int16)READ_LE_UINT16((shape+3))) * mult) >> 8; } int16 ScreenAnimator::fetchAnimHeight(const uint8 *shape, int16 mult) { debugC(9, kDebugLevelAnimator, "ScreenAnimator::fetchAnimHeight(%p, %d)", (const void *)shape, mult); - if (_vm->features() & GF_TALKIE) + if (_vm->gameFlags().useAltShapeHeader) shape += 2; return (int16)(((int8)*(shape+2)) * mult) >> 8; } diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index 9fb2fd3a02..f8827c8399 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -508,16 +508,16 @@ void KyraEngine::setGUILabels() { int walkspeedGarbageOffset = 36; int menuLabelGarbageOffset = 0; - if (_features & GF_TALKIE) { - if (_features & GF_ENGLISH) { + if (_flags.isTalkie) { + if (_flags.lang == Common::EN_ANY) { offset = 52; - } else if (_features & GF_GERMAN) { + } else if (_flags.lang == Common::DE_DEU) { offset = 30; - } else if (_features & GF_FRENCH) { + } else if (_flags.lang == Common::FR_FRA) { offset = 6; } walkspeedGarbageOffset = 48; - } else if (_features & GF_SPANISH) { + } else if (_flags.lang == Common::ES_ESP) { offset = -4; menuLabelGarbageOffset = 72; } @@ -572,7 +572,7 @@ void KyraEngine::setGUILabels() { // Main Menu _menu[5].item[5].itemString = &_guiStrings[19 + offset][menuLabelGarbageOffset]; - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { // Text & Voice _voiceTextString = _guiStrings[28 + offset]; } @@ -1179,7 +1179,7 @@ int KyraEngine::gui_gameControlsMenu(Button *button) { _screen->loadPageFromDisk("SEENPAGE.TMP", 0); _screen->savePageToDisk("SEENPAGE.TMP", 0); - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { //_menu[5].width = 230; for (int i = 0; i < 5; i++) { @@ -1260,7 +1260,7 @@ void KyraEngine::gui_setupControls(Menu &menu) { int textControl = 3; int clickableOffset = 8; - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { textControl = 4; clickableOffset = 11; @@ -1592,7 +1592,7 @@ void KyraEngine::gui_drawMainBox(int x, int y, int w, int h, int fill) { static const uint8 kyra2ColorTable[] = { 0x0, 0x19, 0x28, 0xc8 }; const uint8 *colorTable; - if (_game == GI_KYRA3) + if (_flags.gameID == GI_KYRA3) colorTable = kyra3ColorTable; else colorTable = kyra2ColorTable; diff --git a/engines/kyra/items.cpp b/engines/kyra/items.cpp index c09bd88374..2cceb4bc00 100644 --- a/engines/kyra/items.cpp +++ b/engines/kyra/items.cpp @@ -878,7 +878,7 @@ void KyraEngine::processSpecialMouseItemFX(int shape, int x, int y, int tableVal debugC(9, kDebugLevelMain, "KyraEngine::processSpecialMouseItemFX(%d, %d, %d, %d, %d, %d)", shape, x, y, tableValue, loopStart, maxLoops); uint8 shapeColorTable[16]; uint8 *shapePtr = _shapes[4+shape] + 10; - if (_features & GF_TALKIE) + if (_flags.useAltShapeHeader) shapePtr += 2; for (int i = 0; i < 16; ++i) { shapeColorTable[i] = shapePtr[i]; diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp index 28de21a792..61ea356dab 100644 --- a/engines/kyra/kyra.cpp +++ b/engines/kyra/kyra.cpp @@ -103,9 +103,7 @@ KyraEngine::KyraEngine(OSystem *system) _scrollUpButton.process0PtrShape = _scrollUpButton.process1PtrShape = _scrollUpButton.process2PtrShape = 0; _scrollDownButton.process0PtrShape = _scrollDownButton.process1PtrShape = _scrollDownButton.process2PtrShape = 0; memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); - _features = 0; _quitFlag = false; - _currHeadShape = 0; } @@ -146,7 +144,7 @@ int KyraEngine::init() { // TODO: We should play the native Kyra 2 Adlib music, but until that // is support, we'll use the automagic MIDI -> Adlib converter. - if (midiDriver == MD_ADLIB && _game == GI_KYRA1) { + if (midiDriver == MD_ADLIB && _flags.gameID == GI_KYRA1) { _sound = new SoundAdlibPC(_mixer, this); assert(_sound); } else { @@ -164,7 +162,7 @@ int KyraEngine::init() { soundMidiPc->hasNativeMT32(native_mt32); // C55 appears to be XMIDI for General MIDI instruments - soundMidiPc->setUseC55(_game == GI_KYRA2 && !native_mt32); + soundMidiPc->setUseC55(_flags.gameID == GI_KYRA2 && !native_mt32); // Unlike some SCUMM games, it's not that the MIDI sounds are // missing. It's just that at least at the time of writing they @@ -413,7 +411,7 @@ KyraEngine_v1::~KyraEngine_v1() { int KyraEngine::go() { - if (_features & GF_FLOPPY && !(_features & GF_AMIGA)) { + if (_res->getFileSize("6.FNT")) { _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); } _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); @@ -421,7 +419,7 @@ int KyraEngine::go() { _abortIntroFlag = false; - if (_features & GF_DEMO) { + if (_flags.isDemo) { seq_demo(); } else { setGameFlag(0xF3); diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h index e7e78ac272..8bab62eab0 100644 --- a/engines/kyra/kyra.h +++ b/engines/kyra/kyra.h @@ -46,19 +46,14 @@ class StaticResource; struct ScriptState; struct ScriptData; -enum { - GF_FLOPPY = 1 << 0, - GF_TALKIE = 1 << 1, - GF_AUDIOCD = 1 << 2, // FM-Towns versions seems to use audio CD - GF_DEMO = 1 << 3, - GF_ENGLISH = 1 << 4, - GF_FRENCH = 1 << 5, - GF_GERMAN = 1 << 6, - GF_SPANISH = 1 << 7, - GF_ITALIAN = 1 << 8, - // other languages here - GF_LNGUNK = 1 << 16, // also used for multi language in kyra3 - GF_AMIGA = 1 << 17 // this is no special version flag yet! +struct GameFlags { + Common::Language lang; + Common::Platform platform; + bool isDemo; + bool useAltShapeHeader; // alternative shape header (uses 2 bytes more, those are unused though) + bool hasAudioCD; + bool isTalkie; + byte gameID; }; enum { @@ -261,8 +256,8 @@ public: uint32 tickLength() const { return _tickLength; } virtual Movie *createWSAMovie(); - uint8 game() const { return _game; } - uint32 features() const { return _features; } + uint8 game() const { return _flags.gameID; } + const GameFlags &gameFlags() const { return _flags; } uint8 **shapes() { return _shapes; } Character *currentCharacter() { return _currentCharacter; } @@ -707,7 +702,7 @@ protected: void gui_printString(const char *string, int x, int y, int col1, int col2, int flags, ...); - uint8 _game; + GameFlags _flags; bool _quitFlag; bool _skipFlag; bool _skipIntroFlag; @@ -721,7 +716,6 @@ protected: uint8 *_shapes[377]; uint16 _gameSpeed; uint16 _tickLength; - uint32 _features; int _lang; int _mouseX, _mouseY; int8 _itemInHand; diff --git a/engines/kyra/kyra2.h b/engines/kyra/kyra2.h index 711ea58d4f..31bfa2d3e0 100644 --- a/engines/kyra/kyra2.h +++ b/engines/kyra/kyra2.h @@ -78,7 +78,7 @@ public: KyraEngine_v2(OSystem *system); ~KyraEngine_v2(); - int setupGameFlags() { _game = GI_KYRA2; return 0; } + int setupGameFlags() { _flags.gameID = GI_KYRA2; return 0; } int go(); diff --git a/engines/kyra/kyra3.cpp b/engines/kyra/kyra3.cpp index f92d0b7cc0..0398d30888 100644 --- a/engines/kyra/kyra3.cpp +++ b/engines/kyra/kyra3.cpp @@ -85,7 +85,7 @@ KyraEngine_v3::~KyraEngine_v3() { } int KyraEngine_v3::setupGameFlags() { - _game = GI_KYRA3; + _flags.gameID = GI_KYRA3; return 0; } diff --git a/engines/kyra/plugin.cpp b/engines/kyra/plugin.cpp index 0ed245cebb..787a756cc7 100644 --- a/engines/kyra/plugin.cpp +++ b/engines/kyra/plugin.cpp @@ -42,56 +42,69 @@ enum { struct GameSettings { const char *gameid; const char *description; - byte id; - uint32 features; const char *md5sum; const char *checkFile; + GameFlags flags; }; struct Kyra1LanguageTable { const char *file; - uint32 language; - Common::Language detLanguage; + Common::Language language; }; namespace { const GameSettings kyra_games[] = { - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_ENGLISH | GF_FLOPPY, // english floppy 1.0 from Malice - "3c244298395520bb62b5edfe41688879", "GEMCUT.EMC" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_ENGLISH | GF_FLOPPY, - "796e44863dd22fa635b042df1bf16673", "GEMCUT.EMC" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_FRENCH | GF_FLOPPY, - "abf8eb360e79a6c2a837751fbd4d3d24", "GEMCUT.EMC" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_GERMAN | GF_FLOPPY, - "6018e1dfeaca7fe83f8d0b00eb0dd049", "GEMCUT.EMC"}, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_GERMAN | GF_FLOPPY, // from Arne.F - "f0b276781f47c130f423ec9679fe9ed9", "GEMCUT.EMC"}, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_SPANISH | GF_FLOPPY, // from VooD - "8909b41596913b3f5deaf3c9f1017b01", "GEMCUT.EMC"}, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_SPANISH | GF_FLOPPY, // floppy 1.8 from clemmy - "747861d2a9c643c59fdab570df5b9093", "GEMCUT.EMC"}, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_ITALIAN | GF_FLOPPY, // from gourry - "ef08c8c237ee1473fd52578303fc36df", "GEMCUT.EMC" }, + // floppy versions + // english + { "kyra1", "The Legend of Kyrandia", "3c244298395520bb62b5edfe41688879", "GEMCUT.EMC", + { Common::EN_ANY, Common::kPlatformPC, 0, 0, 0, 0, GI_KYRA1 } }, + { "kyra1", "The Legend of Kyrandia", "796e44863dd22fa635b042df1bf16673", "GEMCUT.EMC", + { Common::EN_ANY, Common::kPlatformPC, 0, 0, 0, 0, GI_KYRA1 } }, + // french + { "kyra1", "The Legend of Kyrandia", "abf8eb360e79a6c2a837751fbd4d3d24", "GEMCUT.EMC", + { Common::FR_FRA, Common::kPlatformPC, 0, 0, 0, 0, GI_KYRA1 } }, + // german + { "kyra1", "The Legend of Kyrandia", "6018e1dfeaca7fe83f8d0b00eb0dd049", "GEMCUT.EMC", + { Common::DE_DEU, Common::kPlatformPC, 0, 0, 0, 0, GI_KYRA1 } }, + { "kyra1", "The Legend of Kyrandia", "f0b276781f47c130f423ec9679fe9ed9", "GEMCUT.EMC", // from Arne.F + { Common::DE_DEU, Common::kPlatformPC, 0, 0, 0, 0, GI_KYRA1 } }, + // spanish + { "kyra1", "The Legend of Kyrandia", "8909b41596913b3f5deaf3c9f1017b01", "GEMCUT.EMC", // from VooD + { Common::ES_ESP, Common::kPlatformPC, 0, 0, 0, 0, GI_KYRA1 } }, + { "kyra1", "The Legend of Kyrandia", "747861d2a9c643c59fdab570df5b9093", "GEMCUT.EMC", // floppy 1.8 from clemmy + { Common::ES_ESP, Common::kPlatformPC, 0, 0, 0, 0, GI_KYRA1 } }, + // italian + { "kyra1", "The Legend of Kyrandia", "ef08c8c237ee1473fd52578303fc36df", "GEMCUT.EMC", // from gourry + { Common::IT_ITA, Common::kPlatformPC, 0, 0, 0, 0, GI_KYRA1 } }, + //{ "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_AMIGA | GF_FLOPPY | GF_ENGLISH, // "2bd1da653eaefd691e050e4a9eb68a64", "GEMCUT.PAK" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_ENGLISH | GF_TALKIE, - "fac399fe62f98671e56a005c5e94e39f", "GEMCUT.PAK" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_GERMAN | GF_TALKIE, - "230f54e6afc007ab4117159181a1c722", "GEMCUT.PAK" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_FRENCH | GF_TALKIE, - "b037c41768b652a040360ffa3556fd2a", "GEMCUT.PAK" }, - { "kyra1", "The Legend of Kyrandia Demo", GI_KYRA1, GF_DEMO | GF_ENGLISH, - "fb722947d94897512b13b50cc84fd648", "DEMO1.WSA" }, + + // CD versions + // english + { "kyra1", "The Legend of Kyrandia", "fac399fe62f98671e56a005c5e94e39f", "GEMCUT.PAK", + { Common::EN_ANY, Common::kPlatformPC, 0, 1, 0, 1, GI_KYRA1 } }, + // german + { "kyra1", "The Legend of Kyrandia", "230f54e6afc007ab4117159181a1c722", "GEMCUT.PAK", + { Common::DE_DEU, Common::kPlatformPC, 0, 1, 0, 1, GI_KYRA1 } }, + // french + { "kyra1", "The Legend of Kyrandia", "b037c41768b652a040360ffa3556fd2a", "GEMCUT.PAK", + { Common::FR_FRA, Common::kPlatformPC, 0, 1, 0, 1, GI_KYRA1 } }, + + // demo versions + // english + { "kyra1", "The Legend of Kyrandia Demo", "fb722947d94897512b13b50cc84fd648", "DEMO1.WSA", + { Common::EN_ANY, Common::kPlatformPC, 1, 0, 0, 0, GI_KYRA1 } }, // kyra 2 games - { "kyra2", "The Legend of Kyrandia: The Hand of Fate", GI_KYRA2, GF_ENGLISH | GF_TALKIE, - "28cbad1c5bf06b2d3825ae57d760d032", "FATE.PAK" }, + { "kyra2", "The Legend of Kyrandia: The Hand of Fate", "28cbad1c5bf06b2d3825ae57d760d032", "FATE.PAK", + { Common::UNK_LANG, Common::kPlatformPC, 0, 0, 0, 0, GI_KYRA2 } }, // talkie version? fixed language version? // kyra 3 games - { "kyra3", "The Legend of Kyrandia: Malcolm's Revenge", - GI_KYRA3, GF_LNGUNK, "3833ff312757b8e6147f464cca0a6587", "ONETIME.PAK" }, + { "kyra3", "The Legend of Kyrandia: Malcolm's Revenge", "3833ff312757b8e6147f464cca0a6587", "ONETIME.PAK", + { Common::UNK_LANG, Common::kPlatformPC, 0, 0, 0, 1, GI_KYRA3 } }, - { 0, 0, 0, 0, 0, 0 } + { 0, 0, 0, 0, { Common::UNK_LANG, Common::kPlatformUnknown, 0, 0, 0, 0, 0 } } }; // Keep list of different supported games @@ -103,46 +116,20 @@ const PlainGameDescriptor kyra_list[] = { }; const Kyra1LanguageTable kyra1_languages[] = { - { "MAIN_FRE.CPS", GF_FRENCH, Common::FR_FRA }, - { "MAIN_GER.CPS", GF_GERMAN, Common::DE_DEU }, - { "MAIN_SPA.CPS", GF_SPANISH, Common::ES_ESP }, - { "MAIN_ITA.CPS", GF_ITALIAN, Common::IT_ITA }, + { "MAIN_FRE.CPS", Common::FR_FRA }, + { "MAIN_GER.CPS", Common::DE_DEU }, + { "MAIN_SPA.CPS", Common::ES_ESP }, + { "MAIN_ITA.CPS", Common::IT_ITA }, // default language - { "MAIN15.CPS", GF_ENGLISH, Common::EN_ANY }, - { "MAIN_ENG.CPS", GF_ENGLISH, Common::EN_ANY }, + { "MAIN15.CPS", Common::EN_ANY }, + { "MAIN_ENG.CPS", Common::EN_ANY }, - { 0, 0, Common::UNK_LANG } + { 0, Common::UNK_LANG } }; -Common::Language convertKyraLang(uint32 features) { - if (features & GF_ENGLISH) { - return Common::EN_ANY; - } else if (features & GF_FRENCH) { - return Common::FR_FRA; - } else if (features & GF_GERMAN) { - return Common::DE_DEU; - } else if (features & GF_SPANISH) { - return Common::ES_ESP; - } else if (features & GF_ITALIAN) { - return Common::IT_ITA; - } - - return Common::UNK_LANG; -} - -Common::Platform convertKyraPlatform(uint32 features) { - if (features & GF_AUDIOCD) { - return Common::kPlatformFMTowns; - } else if (features & GF_AMIGA) { - return Common::kPlatformAmiga; - } - - return Common::kPlatformPC; -} - -const char *getKyraVersion(uint32 features) { - if (features & GF_TALKIE) { +const char *getKyraVersion(const GameFlags &flags) { + if (flags.isTalkie) { return "CD"; } @@ -204,8 +191,8 @@ DetectedGameList Engine_KYRA_detectGames(const FSList &fslist) { for (g = kyra_games; g->gameid; g++) { if (strcmp(g->md5sum, (char *)md5str) == 0) { - DetectedGame dg(*g, convertKyraLang(g->features), convertKyraPlatform(g->features)); - dg.updateDesc(getKyraVersion(g->features)); + DetectedGame dg(*g, g->flags.lang, g->flags.platform); + dg.updateDesc(getKyraVersion(g->flags)); detectedGames.push_back(dg); } @@ -268,7 +255,6 @@ int KyraEngine_v1::setupGameFlags() { bool versionFound = false; bool fileFound = false; - _features = 0; memset(md5str, 0, sizeof(md5str)); for (g = kyra_games; g->gameid; g++) { if (scumm_stricmp(g->gameid, "kyra1")) @@ -286,8 +272,7 @@ int KyraEngine_v1::setupGameFlags() { continue; if (strcmp(g->md5sum, (char *)md5str) == 0) { - _features = g->features; - _game = g->id; + _flags = g->flags; if (g->description) g_system->setWindowCaption(g->description); @@ -300,26 +285,24 @@ int KyraEngine_v1::setupGameFlags() { if (fileFound) { if (!versionFound) { printf("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team\n", md5str); - _features = 0; - _game = GI_KYRA1; + _flags.gameID = GI_KYRA1; if (Common::File::exists("INTRO.VRM")) { - _features |= GF_TALKIE; - } else { - _features |= GF_FLOPPY; + _flags.isTalkie = 1; + _flags.useAltShapeHeader = 1; } // try to detect the language const Kyra1LanguageTable *lang = kyra1_languages; for (; lang->file; ++lang) { if (Common::File::exists(lang->file)) { - _features |= lang->language; + _flags.lang = lang->language; versionFound = true; break; } } if (!versionFound) { - _features |= GF_LNGUNK; + _flags.lang = Common::UNK_LANG; } } } else { diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index 7f633f0a48..4e09641d7e 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -47,11 +47,11 @@ Resource::Resource(KyraEngine *engine) { } // We only need kyra.dat for the demo. - if (_engine->features() & GF_DEMO) + if (_engine->gameFlags().isDemo) return; // only VRM file we need in the *whole* game for kyra1 - if (_engine->features() & GF_TALKIE) { + if (_engine->gameFlags().isTalkie) { loadPakFile("CHAPTER1.VRM"); } } else if (_engine->game() == GI_KYRA3) { @@ -70,7 +70,7 @@ Resource::Resource(KyraEngine *engine) { error("invalid game path '%s'", dir.path().c_str()); } - if (_engine->game() == GI_KYRA1 && (_engine->features() & GF_TALKIE)) { + if (_engine->game() == GI_KYRA1 && _engine->gameFlags().isTalkie) { static const char *list[] = { "adl.pak", "col.pak", "finale.pak", "intro1.pak", "intro2.pak", "intro3.pak", "intro4.pak", "misc.pak", "snd.pak", "startup.pak", "xmi.pak", 0 @@ -122,7 +122,7 @@ bool Resource::loadPakFile(const Common::String &filename) { PAKFile *file = 0; - file = new PAKFile(filename.c_str(), handle.name(), handle, (_engine->features() & GF_AMIGA) != 0); + file = new PAKFile(filename.c_str(), handle.name(), handle, (_engine->gameFlags().platform == Common::kPlatformAmiga)); handle.close(); if (!file) diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp index 17e40b296e..45d34de88e 100644 --- a/engines/kyra/saveload.cpp +++ b/engines/kyra/saveload.cpp @@ -32,6 +32,12 @@ #define CURRENT_VERSION 6 +// TODO: our current savefiles still use the old +// flag system to check the version, we should +// change that some day, but for now it works +#define GF_FLOPPY (1 << 0) +#define GF_TALKIE (1 << 1) + namespace Kyra { void KyraEngine::loadGame(const char *fileName) { debugC(9, kDebugLevelMain, "loadGame('%s')", fileName); @@ -63,13 +69,13 @@ void KyraEngine::loadGame(const char *fileName) { in->read(saveName, 31); if (version >= 2) { - uint32 gameFlags = in->readUint32BE(); - if ((gameFlags & GF_FLOPPY) && !(_features & GF_FLOPPY)) { - warning("can not load floppy savefile for this (non floppy) gameversion"); + uint32 flags = in->readUint32BE(); + if ((flags & GF_FLOPPY) && _flags.isTalkie) { + warning("Can not load floppy savefile for this (non floppy) gameversion"); delete in; return; - } else if ((gameFlags & GF_TALKIE) && !(_features & GF_TALKIE)) { - warning("can not load cdrom savefile for this (non cdrom) gameversion"); + } else if ((flags & GF_TALKIE) && !(_flags.isTalkie)) { + warning("Can not load cdrom savefile for this (non cdrom) gameversion"); delete in; return; } @@ -81,7 +87,7 @@ void KyraEngine::loadGame(const char *fileName) { snd_playWanderScoreViaMap(0, 1); // unload the current voice file should fix some problems with voices - if (_currentRoom != 0xFFFF && (_features & GF_TALKIE)) { + if (_currentRoom != 0xFFFF && _flags.isTalkie) { char file[32]; assert(_currentRoom < _roomTableSize); int tableId = _roomTable[_currentRoom].nameIndex; @@ -259,7 +265,7 @@ void KyraEngine::saveGame(const char *fileName, const char *saveName) { out->writeUint32BE(MKID_BE('KYRA')); out->writeUint32BE(CURRENT_VERSION); out->write(saveName, 31); - out->writeUint32BE(_features); + out->writeUint32BE((_flags.isTalkie ? GF_TALKIE : GF_FLOPPY)); for (int i = 0; i < 11; i++) { out->writeUint16BE(_characterList[i].sceneId); diff --git a/engines/kyra/scene.cpp b/engines/kyra/scene.cpp index e3436a1126..66ba0c69a9 100644 --- a/engines/kyra/scene.cpp +++ b/engines/kyra/scene.cpp @@ -195,7 +195,7 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int void KyraEngine::transcendScenes(int roomIndex, int roomName) { debugC(9, kDebugLevelMain, "KyraEngine::transcendScenes(%d, %d)", roomIndex, roomName); assert(roomIndex < _roomTableSize); - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { char file[32]; assert(roomIndex < _roomTableSize); int tableId = _roomTable[roomIndex].nameIndex; @@ -1557,7 +1557,7 @@ int KyraEngine::getMoveTableSize(int *moveTable) { void KyraEngine::setupSceneResource(int sceneId) { debugC(9, kDebugLevelMain, "KyraEngine::setupSceneResource(%d)", sceneId); - if (_features & GF_FLOPPY) + if (!_flags.isTalkie) return; if (_currentRoom != 0xFFFF) { diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 03887b45e4..c36e8366c5 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -919,7 +919,7 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int int ppc = (flags >> 8) & 0x3F; const uint8 *src = shapeData; - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) { + if (_vm->gameFlags().useAltShapeHeader) { src += 2; } uint16 shapeFlags = READ_LE_UINT16(src); src += 2; @@ -970,7 +970,7 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int // only used if shapeFlag & 1 is NOT zero const uint8 *colorTable = shapeData + 10; - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) { + if (_vm->gameFlags().useAltShapeHeader) { colorTable += 2; } @@ -1635,7 +1635,7 @@ uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { } int16 shapeSize2 = shapeSize; - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) { + if (_vm->gameFlags().useAltShapeHeader) { shapeSize += 12; } else { shapeSize += 10; @@ -1651,7 +1651,7 @@ uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { assert(newShape); byte *dst = newShape; - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) + if (_vm->gameFlags().useAltShapeHeader) dst += 2; WRITE_LE_UINT16(dst, (flags & 3)); dst += 2; *dst = h; dst += 1; @@ -1719,7 +1719,7 @@ uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { if (!(flags & 2)) { if (shapeSize > _animBlockSize) { dst = newShape; - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) { + if (_vm->gameFlags().useAltShapeHeader) { dst += 2; } flags = READ_LE_UINT16(dst); @@ -1727,7 +1727,7 @@ uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { WRITE_LE_UINT16(dst, flags); } else { src = newShape; - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) { + if (_vm->gameFlags().useAltShapeHeader) { src += 2; } if (flags & 1) { @@ -1759,14 +1759,14 @@ uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { } dst = newShape; - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) { + if (_vm->gameFlags().useAltShapeHeader) { dst += 2; } WRITE_LE_UINT16((dst + 6), shapeSize); if (flags & 1) { dst = newShape + 10; - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) { + if (_vm->gameFlags().useAltShapeHeader) { dst += 2; } src = &table[0x100]; @@ -1955,13 +1955,13 @@ void Screen::setMouseCursor(int x, int y, byte *shape) { // if mouseDisabled // return _mouseShape - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) + if (_vm->gameFlags().useAltShapeHeader) shape += 2; int mouseHeight = *(shape + 2); int mouseWidth = (READ_LE_UINT16(shape + 3)) + 2; - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) + if (_vm->gameFlags().useAltShapeHeader) shape -= 2; uint8 *cursor = new uint8[mouseHeight * mouseWidth]; @@ -2039,7 +2039,7 @@ byte Screen::getShapeFlag2(int x, int y) { int Screen::setNewShapeHeight(uint8 *shape, int height) { debugC(9, kDebugLevelScreen, "Screen::setNewShapeHeight(%p, %d)", (const void *)shape, height); - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) + if (_vm->gameFlags().useAltShapeHeader) shape += 2; int oldHeight = shape[2]; shape[2] = height; @@ -2048,7 +2048,7 @@ int Screen::setNewShapeHeight(uint8 *shape, int height) { int Screen::resetShapeHeight(uint8 *shape) { debugC(9, kDebugLevelScreen, "Screen::setNewShapeHeight(%p)", (const void *)shape); - if ((_vm->game() == GI_KYRA1) && (_vm->features() & GF_TALKIE)) + if (_vm->gameFlags().useAltShapeHeader) shape += 2; int oldHeight = shape[2]; shape[2] = shape[5]; diff --git a/engines/kyra/script_v1.cpp b/engines/kyra/script_v1.cpp index 125414d557..42d5f22f7e 100644 --- a/engines/kyra/script_v1.cpp +++ b/engines/kyra/script_v1.cpp @@ -43,7 +43,7 @@ int KyraEngine::o1_magicInMouseItem(ScriptState *script) { int KyraEngine::o1_characterSays(ScriptState *script) { _skipFlag = false; - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { debugC(3, kDebugLevelScriptFuncs, "o1_characterSays(%p) (%d, '%s', %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); if (speechEnabled()) { snd_voiceWaitForFinish(); @@ -615,7 +615,7 @@ int KyraEngine::o1_loadPageFromDisk(ScriptState *script) { } int KyraEngine::o1_customPrintTalkString(ScriptState *script) { - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { debugC(3, kDebugLevelScriptFuncs, "o1_customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF); if (speechEnabled()) { @@ -1073,12 +1073,12 @@ int KyraEngine::o1_specialEventDisplayBrynnsNote(ScriptState *script) { _screen->hideMouse(); _screen->savePageToDisk("HIDPAGE.TMP", 2); _screen->savePageToDisk("SEENPAGE.TMP", 0); - if (_features & GF_TALKIE) { - if (_features & GF_ENGLISH) { + if (_flags.isTalkie) { + if (_flags.lang == Common::EN_ANY) { _screen->loadBitmap("NOTEENG.CPS", 3, 3, 0); - } else if (_features & GF_FRENCH) { + } else if (_flags.lang == Common::FR_FRA) { _screen->loadBitmap("NOTEFRE.CPS", 3, 3, 0); - } else if (_features & GF_GERMAN) { + } else if (_flags.lang == Common::DE_DEU) { _screen->loadBitmap("NOTEGER.CPS", 3, 3, 0); } } else { @@ -1663,7 +1663,7 @@ int KyraEngine::o1_setScaleDepthTableValue(ScriptState *script) { } int KyraEngine::o1_message(ScriptState *script) { - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { debugC(3, kDebugLevelScriptFuncs, "o1_message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2)); drawSentenceCommand(stackPosString(1), stackPos(2)); } else { diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp index e954f529d4..e680eac2a0 100644 --- a/engines/kyra/seqplayer.cpp +++ b/engines/kyra/seqplayer.cpp @@ -74,7 +74,7 @@ uint8 *SeqPlayer::setPanPages(int pageNum, int shape) { uint16 numShapes = READ_LE_UINT16(data); if (shape < numShapes) { uint32 offs = 0; - if (_vm->features() & GF_TALKIE) { + if (_vm->gameFlags().isTalkie) { offs = READ_LE_UINT32(data + 2 + shape * 4); } else { offs = READ_LE_UINT16(data + 2 + shape * 2); @@ -260,7 +260,7 @@ void SeqPlayer::s1_printText() { int x = (Screen::SCREEN_W - _screen->getTextWidth(str)) / 2; _screen->printText(str, x, 180, 0xF, 0xC); } else { - _seqDisplayedTextTimer = _system->getMillis() + 1000 / ((_vm->features() & GF_FRENCH) ? 120 : 60); + _seqDisplayedTextTimer = _system->getMillis() + 1000 / ((_vm->gameFlags().lang == Common::FR_FRA) ? 120 : 60); _seqDisplayedText = txt; _seqDisplayedChar = 0; const char *str = _vm->seqTextsTable()[_seqDisplayedText]; @@ -326,9 +326,9 @@ void SeqPlayer::s1_copyRegion() { void SeqPlayer::s1_copyRegionSpecial() { static const uint8 colorMap[] = { 0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0 }; const char *copyStr = 0; - if (_vm->features() & GF_FLOPPY || _vm->features() & GF_DEMO) { + if (!_vm->gameFlags().isTalkie) { copyStr = "Copyright (c) 1992 Westwood Studios"; - } else if (_vm->features() & GF_TALKIE) { + } else { copyStr = "Copyright (c) 1992,1993 Westwood Studios"; } @@ -419,7 +419,7 @@ void SeqPlayer::s1_playTrack() { } void SeqPlayer::s1_allocTempBuffer() { - if (_vm->features() & GF_DEMO) { + if (_vm->gameFlags().isDemo) { _seqQuitFlag = true; } else { if (!_specialBuffer && !_copyViewOffs) { @@ -562,14 +562,12 @@ bool SeqPlayer::playSequence(const uint8 *seqData, bool skipSeq) { const SeqEntry* commands; int numCommands; - if (_vm->features() & GF_FLOPPY || _vm->features() & GF_DEMO) { - commands = floppySeqProcs; - numCommands = ARRAYSIZE(floppySeqProcs); - } else if (_vm->features() & GF_TALKIE) { + if (_vm->gameFlags().isTalkie) { commands = cdromSeqProcs; numCommands = ARRAYSIZE(cdromSeqProcs); } else { - error("No commandlist found"); + commands = floppySeqProcs; + numCommands = ARRAYSIZE(floppySeqProcs); } bool seqSkippedFlag = false; @@ -619,7 +617,7 @@ bool SeqPlayer::playSequence(const uint8 *seqData, bool skipSeq) { if (_vm->seqTextsTable()[_seqDisplayedText][_seqDisplayedChar] == '\0') { _seqDisplayedTextTimer = 0xFFFFFFFF; } else { - _seqDisplayedTextTimer = _system->getMillis() + 1000 / ((_vm->features() & GF_FRENCH) ? 120 : 60); + _seqDisplayedTextTimer = _system->getMillis() + 1000 / ((_vm->gameFlags().lang == Common::FR_FRA) ? 120 : 60); } } } diff --git a/engines/kyra/sequences_v1.cpp b/engines/kyra/sequences_v1.cpp index 11da73925b..ed53396482 100644 --- a/engines/kyra/sequences_v1.cpp +++ b/engines/kyra/sequences_v1.cpp @@ -88,7 +88,7 @@ void KyraEngine::seq_demo() { void KyraEngine::seq_intro() { debugC(9, kDebugLevelMain, "KyraEngine::seq_intro()"); - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { _res->loadPakFile("INTRO.VRM"); } @@ -119,7 +119,7 @@ void KyraEngine::seq_intro() { _seq->setCopyViewOffs(false); _sound->haltTrack(); _sound->voiceStop(); - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { _res->unloadPakFile("INTRO.VRM"); } } @@ -194,17 +194,17 @@ void KyraEngine::seq_introStory() { debugC(9, kDebugLevelMain, "KyraEngine::seq_introStory()"); _screen->clearPage(3); _screen->clearPage(0); - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { return; - } else if (_features & GF_ENGLISH) { + } else if (_flags.lang == Common::EN_ANY) { _screen->loadBitmap("TEXT.CPS", 3, 3, 0); - } else if (_features & GF_GERMAN) { + } else if (_flags.lang == Common::DE_DEU) { _screen->loadBitmap("TEXT_GER.CPS", 3, 3, 0); - } else if (_features & GF_FRENCH) { + } else if (_flags.lang == Common::FR_FRA) { _screen->loadBitmap("TEXT_FRE.CPS", 3, 3, 0); - } else if (_features & GF_SPANISH) { + } else if (_flags.lang == Common::ES_ESP) { _screen->loadBitmap("TEXT_SPA.CPS", 3, 3, 0); - } else if (_features & GF_ITALIAN) { + } else if (_flags.lang == Common::IT_ITA) { _screen->loadBitmap("TEXT_ITA.CPS", 3, 3, 0); } else { warning("no story graphics file found"); @@ -528,7 +528,7 @@ void KyraEngine::seq_winterScroll1() { snd_playSoundEffect(0x20); uint8 numFrames, midpoint; - if (_features & GF_TALKIE) { + if (_flags.isTalkie) { numFrames = 18; midpoint = 136; } else { @@ -1051,7 +1051,7 @@ void KyraEngine::seq_playCredits() { memset(strings, 0, sizeof(strings)); _screen->hideMouse(); - if (_features & GF_FLOPPY) { + if (!_flags.isTalkie) { _screen->loadFont(Screen::FID_CRED6_FNT, "CREDIT6.FNT"); _screen->loadFont(Screen::FID_CRED8_FNT, "CREDIT8.FNT"); } else @@ -1098,12 +1098,12 @@ void KyraEngine::seq_playCredits() { if (*currentString == 1) { currentString++; - if (_features & GF_FLOPPY) + if (!_flags.isTalkie) _screen->setFont(Screen::FID_CRED6_FNT); } else { if (*currentString == 2) currentString++; - if (_features & GF_FLOPPY) + if (!_flags.isTalkie) _screen->setFont(Screen::FID_CRED8_FNT); } strings[i].font = _screen->_currentFont; diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index 1b7fcda97f..1b076444b4 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -434,11 +434,11 @@ void SoundMidiPC::beginFadeOut() { bool KyraEngine::speechEnabled() { - return _features & GF_TALKIE && (_configVoice == 1 || _configVoice == 2); + return _flags.isTalkie && (_configVoice == 1 || _configVoice == 2); } bool KyraEngine::textEnabled() { - return _features & GF_FLOPPY || (_configVoice == 0 || _configVoice == 2); + return !_flags.isTalkie || (_configVoice == 0 || _configVoice == 2); } void KyraEngine::snd_playTheme(int file, int track) { diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 08a8cc4567..b749f5f056 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -44,9 +44,51 @@ bool StaticResource::checkKyraDat() { return true; } +// 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_AUDIOCD = 1 << 2, // FM-Towns versions seems to use audio CD + GF_DEMO = 1 << 3, + GF_ENGLISH = 1 << 4, + GF_FRENCH = 1 << 5, + GF_GERMAN = 1 << 6, + GF_SPANISH = 1 << 7, + GF_ITALIAN = 1 << 8, + // other languages here + GF_LNGUNK = 1 << 16, // also used for multi language in kyra3 + GF_AMIGA = 1 << 17 // this is no special version flag yet! +}; + #define GAME_FLAGS (GF_FLOPPY | GF_TALKIE | GF_DEMO | GF_AUDIOCD) #define LANGUAGE_FLAGS (GF_ENGLISH | GF_FRENCH | GF_GERMAN | GF_SPANISH | GF_ITALIAN | GF_LNGUNK) +uint32 createFeatures(const GameFlags &flags) { + if (flags.isTalkie) + return GF_TALKIE; + if (flags.isDemo) + return GF_DEMO; + if (flags.hasAudioCD) + return GF_AUDIOCD; + return GF_FLOPPY; +} + +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; + return GF_LNGUNK; +} + struct LanguageTypes { uint32 flags; const char *ext; @@ -180,8 +222,10 @@ bool StaticResource::init() { if (gameID != _engine->game()) { error("invalid game id (%d)", gameID); } - if ((featuresValue & GAME_FLAGS) != (_engine->features() & GAME_FLAGS)) { - error("your data file has a different game flags (0x%.08X has the data and your version has 0x%.08X)", (featuresValue & GAME_FLAGS), (_engine->features() & GAME_FLAGS)); + + uint32 gameFeatures = createFeatures(_engine->gameFlags()); + if ((featuresValue & GAME_FLAGS) != gameFeatures) { + error("your data file has a different game flags (0x%.08X has the data and your version has 0x%.08X)", (featuresValue & GAME_FLAGS), gameFeatures); } // load all tables for now @@ -351,7 +395,7 @@ const void *StaticResource::getData(int id, int requesttype, int &size) { bool StaticResource::loadLanguageTable(const char *filename, void *&ptr, int &size) { char file[64]; for (int i = 0; languages[i].ext; ++i) { - if (languages[i].flags != (_engine->features() & LANGUAGE_FLAGS)) { + if (languages[i].flags != createLanguage(_engine->gameFlags())) { continue; } @@ -540,9 +584,9 @@ void StaticResource::freePaletteTable(void *&ptr, int &size) { uint8 *StaticResource::getFile(const char *name, int &size) { char buffer[64]; const char *ext = ""; - if (_engine->features() & GF_TALKIE) { + if (_engine->gameFlags().isTalkie) { ext = ".CD"; - } else if (_engine->features() & GF_DEMO) { + } else if (_engine->gameFlags().isDemo) { ext = ".DEM"; } snprintf(buffer, 64, "%s%s", name, ext); @@ -769,17 +813,17 @@ void KyraEngine::loadButtonShapes() { void KyraEngine::loadMainScreen(int page) { _screen->clearPage(page); - if ((_features & GF_ENGLISH) && (_features & GF_FLOPPY)) + if (_flags.lang == Common::EN_ANY && !_flags.isTalkie) _screen->loadBitmap("MAIN15.CPS", page, page, 0); - else if ((_features & GF_ENGLISH) && (_features & GF_TALKIE)) + else if (_flags.lang == Common::EN_ANY && _flags.isTalkie) _screen->loadBitmap("MAIN_ENG.CPS", page, page, 0); - else if (_features & GF_FRENCH) + else if (_flags.lang == Common::FR_FRA) _screen->loadBitmap("MAIN_FRE.CPS", page, page, 0); - else if (_features & GF_GERMAN) + else if (_flags.lang == Common::DE_DEU) _screen->loadBitmap("MAIN_GER.CPS", page, page, 0); - else if (_features & GF_SPANISH) + else if (_flags.lang == Common::ES_ESP) _screen->loadBitmap("MAIN_SPA.CPS", page, page, 0); - else if (_features & GF_ITALIAN) + else if (_flags.lang == Common::IT_ITA) _screen->loadBitmap("MAIN_ITA.CPS", page, page, 0); else warning("no main graphics file found"); diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp index 3aa5425d5f..ec3670106e 100644 --- a/engines/kyra/wsamovie.cpp +++ b/engines/kyra/wsamovie.cpp @@ -51,7 +51,7 @@ int WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { _deltaBufferSize = READ_LE_UINT16(wsaData); wsaData += 2; _offscreenBuffer = NULL; _flags = 0; - if (_vm->features() & GF_TALKIE) { + if (_vm->gameFlags().isTalkie) { flags = READ_LE_UINT16(wsaData); wsaData += 2; } |