diff options
-rw-r--r-- | audio/decoders/qdm2.cpp | 104 | ||||
-rw-r--r-- | base/main.cpp | 4 | ||||
-rw-r--r-- | common/quicktime.cpp | 15 | ||||
-rw-r--r-- | common/quicktime.h | 36 | ||||
-rw-r--r-- | engines/advancedDetector.cpp | 13 | ||||
-rw-r--r-- | engines/agos/script_s1.cpp | 6 | ||||
-rw-r--r-- | engines/gob/detection_tables.h | 14 | ||||
-rw-r--r-- | engines/metaengine.h | 9 | ||||
-rw-r--r-- | engines/queen/queen.cpp | 8 | ||||
-rw-r--r-- | engines/sci/engine/features.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/workarounds.cpp | 2 | ||||
-rw-r--r-- | engines/sci/sound/soundcmd.cpp | 5 | ||||
-rw-r--r-- | engines/sky/control.cpp | 3 | ||||
-rw-r--r-- | engines/sky/detection.cpp | 8 |
14 files changed, 122 insertions, 107 deletions
diff --git a/audio/decoders/qdm2.cpp b/audio/decoders/qdm2.cpp index 735fb2b6a0..2de7a68dd9 100644 --- a/audio/decoders/qdm2.cpp +++ b/audio/decoders/qdm2.cpp @@ -1695,7 +1695,6 @@ void QDM2Stream::initVlc(void) { QDM2Stream::QDM2Stream(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) { uint32 tmp; - int32 tmp_s; int tmp_val; int i; @@ -1736,91 +1735,44 @@ QDM2Stream::QDM2Stream(Common::SeekableReadStream *extraData, DisposeAfterUse::F _superblocktype_2_3 = 0; _hasErrors = false; - // Rewind extraData stream from any previous calls... + // The QDM2 "extra data" is really just an amalgam of three QuickTime + // atoms needed to correctly set up the decoder. + + // Rewind extraData stream from any previous calls extraData->seek(0, SEEK_SET); - tmp_s = extraData->readSint32BE(); - debug(1, "QDM2Stream::QDM2Stream() extraSize: %d", tmp_s); - if ((extraData->size() - extraData->pos()) / 4 + 1 != tmp_s) - warning("QDM2Stream::QDM2Stream() extraSize mismatch - Expected %d", (extraData->size() - extraData->pos()) / 4 + 1); - if (tmp_s < 12) - error("QDM2Stream::QDM2Stream() Insufficient extraData"); - - tmp = extraData->readUint32BE(); - debug(1, "QDM2Stream::QDM2Stream() extraTag: %d", tmp); - if (tmp != MKTAG('f','r','m','a')) - warning("QDM2Stream::QDM2Stream() extraTag mismatch"); - - tmp = extraData->readUint32BE(); - debug(1, "QDM2Stream::QDM2Stream() extraType: %d", tmp); - if (tmp == MKTAG('Q','D','M','C')) - warning("QDM2Stream::QDM2Stream() QDMC stream type not supported"); - else if (tmp != MKTAG('Q','D','M','2')) - error("QDM2Stream::QDM2Stream() Unsupported stream type"); - - tmp_s = extraData->readSint32BE(); - debug(1, "QDM2Stream::QDM2Stream() extraSize2: %d", tmp_s); - if ((extraData->size() - extraData->pos()) + 4 != tmp_s) - warning("QDM2Stream::QDM2Stream() extraSize2 mismatch - Expected %d", (extraData->size() - extraData->pos()) + 4); - - tmp = extraData->readUint32BE(); - debug(1, "QDM2Stream::QDM2Stream() extraTag2: %d", tmp); - if (tmp != MKTAG('Q','D','C','A')) - warning("QDM2Stream::QDM2Stream() extraTag2 mismatch"); - - if (extraData->readUint32BE() != 1) - warning("QDM2Stream::QDM2Stream() u0 field not 1"); + // First, the frma atom + uint32 frmaSize = extraData->readUint32BE(); + if (frmaSize != 12) + error("Invalid QDM2 frma atom"); - _channels = extraData->readUint32BE(); - debug(1, "QDM2Stream::QDM2Stream() channels: %d", _channels); + if (extraData->readUint32BE() != MKTAG('f', 'r', 'm', 'a')) + error("Failed to find frma atom for QDM2"); - _sampleRate = extraData->readUint32BE(); - debug(1, "QDM2Stream::QDM2Stream() sampleRate: %d", _sampleRate); + uint32 version = extraData->readUint32BE(); + if (version == MKTAG('Q', 'D', 'M', 'C')) + error("Unhandled QDMC sound"); + else if (version != MKTAG('Q', 'D', 'M', '2')) + error("Failed to find QDM2 tag in frma atom"); - _bitRate = extraData->readUint32BE(); - debug(1, "QDM2Stream::QDM2Stream() bitRate: %d", _bitRate); + // Second, the QDCA atom + uint32 qdcaSize = extraData->readUint32BE(); + if (qdcaSize > (uint32)(extraData->size() - extraData->pos())) + error("Invalid QDM2 QDCA atom"); - _blockSize = extraData->readUint32BE(); - debug(1, "QDM2Stream::QDM2Stream() blockSize: %d", _blockSize); + if (extraData->readUint32BE() != MKTAG('Q', 'D', 'C', 'A')) + error("Failed to find QDCA atom for QDM2"); - _frameSize = extraData->readUint32BE(); - debug(1, "QDM2Stream::QDM2Stream() frameSize: %d", _frameSize); + extraData->readUint32BE(); // unknown + _channels = extraData->readUint32BE(); + _sampleRate = extraData->readUint32BE(); + _bitRate = extraData->readUint32BE(); + _blockSize = extraData->readUint32BE(); + _frameSize = extraData->readUint32BE(); _packetSize = extraData->readUint32BE(); - debug(1, "QDM2Stream::QDM2Stream() packetSize: %d", _packetSize); - - if (extraData->size() - extraData->pos() != 0) { - tmp_s = extraData->readSint32BE(); - debug(1, "QDM2Stream::QDM2Stream() extraSize3: %d", tmp_s); - if (extraData->size() + 4 != tmp_s) - warning("QDM2Stream::QDM2Stream() extraSize3 mismatch - Expected %d", extraData->size() + 4); - - tmp = extraData->readUint32BE(); - debug(1, "QDM2Stream::QDM2Stream() extraTag3: %d", tmp); - if (tmp != MKTAG('Q','D','C','P')) - warning("QDM2Stream::QDM2Stream() extraTag3 mismatch"); - - if ((float)extraData->readUint32BE() != 1.0) - warning("QDM2Stream::QDM2Stream() uf0 field not 1.0"); - - if (extraData->readUint32BE() != 0) - warning("QDM2Stream::QDM2Stream() u1 field not 0"); - if ((float)extraData->readUint32BE() != 1.0) - warning("QDM2Stream::QDM2Stream() uf1 field not 1.0"); - - if ((float)extraData->readUint32BE() != 1.0) - warning("QDM2Stream::QDM2Stream() uf2 field not 1.0"); - - if (extraData->readUint32BE() != 27) - warning("QDM2Stream::QDM2Stream() u2 field not 27"); - - if (extraData->readUint32BE() != 8) - warning("QDM2Stream::QDM2Stream() u3 field not 8"); - - if (extraData->readUint32BE() != 0) - warning("QDM2Stream::QDM2Stream() u4 field not 0"); - } + // Third, we don't care about the QDCP atom _fftOrder = Common::intLog2(_frameSize) + 1; _fftFrameSize = 2 * _frameSize; // complex has two floats diff --git a/base/main.cpp b/base/main.cpp index 99dcac63d3..c657488758 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -206,8 +206,8 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const // Initialize any game-specific keymaps engine->initKeymap(); - // Set default values to the custom engine options - const ExtraGuiOptions engineOptions = (*plugin)->getExtraGuiOptions(ConfMan.getActiveDomainName()); + // Set default values for all of the custom engine options + const ExtraGuiOptions engineOptions = (*plugin)->getExtraGuiOptions(Common::String()); for (uint i = 0; i < engineOptions.size(); i++) { ConfMan.registerDefault(engineOptions[i].configOption, engineOptions[i].defaultState); } diff --git a/common/quicktime.cpp b/common/quicktime.cpp index fb01e8de28..5176f83a35 100644 --- a/common/quicktime.cpp +++ b/common/quicktime.cpp @@ -164,6 +164,7 @@ void QuickTimeParser::initParseTable() { { &QuickTimeParser::readCMOV, MKTAG('c', 'm', 'o', 'v') }, { &QuickTimeParser::readWAVE, MKTAG('w', 'a', 'v', 'e') }, { &QuickTimeParser::readESDS, MKTAG('e', 's', 'd', 's') }, + { &QuickTimeParser::readSMI, MKTAG('S', 'M', 'I', ' ') }, { 0, 0 } }; @@ -687,7 +688,7 @@ int QuickTimeParser::readWAVE(Atom atom) { return -1; if (track->sampleDescs[0]->getCodecTag() == MKTAG('Q', 'D', 'M', '2')) // Read extra data for QDM2 - track->extraData = _fd->readStream(atom.size - 8); + track->extraData = _fd->readStream(atom.size); else if (atom.size > 8) return readDefault(atom); else @@ -761,6 +762,18 @@ int QuickTimeParser::readESDS(Atom atom) { return 0; } +int QuickTimeParser::readSMI(Atom atom) { + if (_tracks.empty()) + return 0; + + Track *track = _tracks.back(); + + // This atom just contains SVQ3 extra data + track->extraData = _fd->readStream(atom.size); + + return 0; +} + void QuickTimeParser::close() { for (uint32 i = 0; i < _tracks.size(); i++) delete _tracks[i]; diff --git a/common/quicktime.h b/common/quicktime.h index efd2adbd21..974502d075 100644 --- a/common/quicktime.h +++ b/common/quicktime.h @@ -77,25 +77,13 @@ public: */ void setChunkBeginOffset(uint32 offset) { _beginOffset = offset; } + /** Find out if this parser has an open file handle */ bool isOpen() const { return _fd != 0; } protected: // This is the file handle from which data is read from. It can be the actual file handle or a decompressed stream. SeekableReadStream *_fd; - DisposeAfterUse::Flag _disposeFileHandle; - - struct Atom { - uint32 type; - uint32 offset; - uint32 size; - }; - - struct ParseTable { - int (QuickTimeParser::*func)(Atom atom); - uint32 type; - }; - struct TimeToSampleEntry { int count; int duration; @@ -174,18 +162,33 @@ protected: virtual SampleDesc *readSampleDesc(Track *track, uint32 format) = 0; - const ParseTable *_parseTable; - bool _foundMOOV; uint32 _timeScale; uint32 _duration; Rational _scaleFactorX; Rational _scaleFactorY; Array<Track *> _tracks; + + void init(); + +private: + struct Atom { + uint32 type; + uint32 offset; + uint32 size; + }; + + struct ParseTable { + int (QuickTimeParser::*func)(Atom atom); + uint32 type; + }; + + DisposeAfterUse::Flag _disposeFileHandle; + const ParseTable *_parseTable; uint32 _beginOffset; MacResManager *_resFork; + bool _foundMOOV; void initParseTable(); - void init(); int readDefault(Atom atom); int readLeaf(Atom atom); @@ -205,6 +208,7 @@ protected: int readCMOV(Atom atom); int readWAVE(Atom atom); int readESDS(Atom atom); + int readSMI(Atom atom); }; } // End of namespace Common diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp index dc7f7e007c..ac06e74e0a 100644 --- a/engines/advancedDetector.cpp +++ b/engines/advancedDetector.cpp @@ -171,12 +171,21 @@ const ExtraGuiOptions AdvancedMetaEngine::getExtraGuiOptions(const Common::Strin if (!_extraGuiOptions) return ExtraGuiOptions(); + ExtraGuiOptions options; + + // If there isn't any target specified, return all available GUI options. + // Only used when an engine starts in order to set option defaults. + if (target.empty()) { + for (const ADExtraGuiOptionsMap *entry = _extraGuiOptions; entry->guioFlag; ++entry) + options.push_back(entry->option); + + return options; + } + // Query the GUI options const Common::String guiOptionsString = ConfMan.get("guioptions", target); const Common::String guiOptions = parseGameGUIOptions(guiOptionsString); - ExtraGuiOptions options; - // Add all the applying extra GUI options. for (const ADExtraGuiOptionsMap *entry = _extraGuiOptions; entry->guioFlag; ++entry) { if (guiOptions.contains(entry->guioFlag)) diff --git a/engines/agos/script_s1.cpp b/engines/agos/script_s1.cpp index a07c05b4fc..a81a363845 100644 --- a/engines/agos/script_s1.cpp +++ b/engines/agos/script_s1.cpp @@ -362,6 +362,12 @@ void AGOSEngine_Simon1::os1_screenTextMsg() { stopAnimateSimon2(2, vgaSpriteId + 2); } + // Several strings in the French version of Simon the Sorcerer 1 set the incorrect width, + // causing crashes, or glitches in subtitles. See bug #3512776 for example. + if (getGameType() == GType_SIMON1 && _language == Common::FR_FRA && stringId == 33245) { + tl->width = 96; + } + if (stringPtr != NULL && stringPtr[0] != 0 && (speechId == 0 || _subtitles)) printScreenText(vgaSpriteId, color, (const char *)stringPtr, tl->x, tl->y, tl->width); diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h index 5c6e919e12..7aa58b9b97 100644 --- a/engines/gob/detection_tables.h +++ b/engines/gob/detection_tables.h @@ -735,6 +735,20 @@ static const GOBGameDescription gameDescriptions[] = { kFeaturesNone, 0, 0, 0 }, + { // Supplied by aldozx in the forums + { + "gob2", + "", + AD_ENTRY1s("intro.stk", "abc3e786cd78197773954c75815b278b", 554721), + ES_ESP, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesNone, + 0, 0, 0 + }, { // Supplied by bgk in bug report #1706861 { "gob2", diff --git a/engines/metaengine.h b/engines/metaengine.h index 632c204978..ffa682fc53 100644 --- a/engines/metaengine.h +++ b/engines/metaengine.h @@ -112,10 +112,17 @@ public: } /** - * Return a list of extra GUI options. + * Return a list of extra GUI options for the specified target. + * If no target is specified, all of the available custom GUI options are + * Returned for the plugin (used to set default values). + * * Currently, this only supports options with checkboxes. * * The default implementation returns an empty list. + * + * @param target name of a config manager target + * @return a list of extra GUI options for an engine plugin and + * target */ virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const { return ExtraGuiOptions(); diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp index 1b07d3c01a..3acc87b856 100644 --- a/engines/queen/queen.cpp +++ b/engines/queen/queen.cpp @@ -112,12 +112,18 @@ int QueenMetaEngine::getMaximumSaveSlot() const { return 99; } const ExtraGuiOptions QueenMetaEngine::getExtraGuiOptions(const Common::String &target) const { Common::String guiOptions; + ExtraGuiOptions options; + + if (target.empty()) { + options.push_back(queenExtraGuiOption); + return options; + } + if (ConfMan.hasKey("guioptions", target)) { guiOptions = ConfMan.get("guioptions", target); guiOptions = parseGameGUIOptions(guiOptions); } - ExtraGuiOptions options; if (!guiOptions.contains(GUIO_NOSPEECH)) options.push_back(queenExtraGuiOption); return options; diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp index a284c319c0..cad95b1c18 100644 --- a/engines/sci/engine/features.cpp +++ b/engines/sci/engine/features.cpp @@ -43,7 +43,7 @@ GameFeatures::GameFeatures(SegManager *segMan, Kernel *kernel) : _segMan(segMan) _sci2StringFunctionType = kSci2StringFunctionUninitialized; #endif _usesCdTrack = Common::File::exists("cdaudio.map"); - if (ConfMan.hasKey("use_cdaudio") && !ConfMan.getBool("use_cdaudio")) + if (!ConfMan.getBool("use_cdaudio")) _usesCdTrack = false; } diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index a556134e32..d7ade85173 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -252,6 +252,7 @@ const SciWorkaroundEntry kDoSoundFade_workarounds[] = { const SciWorkaroundEntry kGetAngle_workarounds[] = { { GID_FANMADE, 516, 992, 0, "Motion", "init", -1, 0, { WORKAROUND_IGNORE, 0 } }, // The Legend of the Lost Jewel Demo (fan made): called with third/fourth parameters as objects { GID_KQ6, -1, 752, 0, "throwDazzle", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // room 740/790 after the Genie is exposed in the Palace (short and long ending), it starts shooting lightning bolts around. An extra 5th parameter is passed - bug #3034610 & #3041734 + { GID_SQ1, -1, 927, 0, "PAvoider", "doit", -1, 0, { WORKAROUND_IGNORE, 0 } }, // all rooms in Ulence Flats after getting the Pilot Droid: called with a single parameter when the droid is in Roger's path - bug #3513207 SCI_WORKAROUNDENTRY_TERMINATOR }; @@ -336,6 +337,7 @@ const SciWorkaroundEntry kIsObject_workarounds[] = { // gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kMemory_workarounds[] = { { GID_LAURABOW2, -1, 999, 0, "", "export 6", -1, 0, { WORKAROUND_FAKE, 0 } }, // during the intro, when exiting the train (room 160), talking to Mr. Augustini, etc. - bug #3034490 + { GID_SQ1, -1, 999, 0, "", "export 6", -1, 0, { WORKAROUND_FAKE, 0 } }, // during walking Roger around Ulence Flats - bug #3513765 SCI_WORKAROUNDENTRY_TERMINATOR }; diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp index 8481f10171..05bb90332a 100644 --- a/engines/sci/sound/soundcmd.cpp +++ b/engines/sci/sound/soundcmd.cpp @@ -44,10 +44,7 @@ SoundCommandParser::SoundCommandParser(ResourceManager *resMan, SegManager *segM // resource number, but it's totally unrelated to the menu music). // The GK1 demo (very late SCI1.1) does the same thing // TODO: Check the QFG4 demo - - // If the prefer_digitalsfx key is missing, default to enable digital SFX - bool preferDigitalSfx = !ConfMan.hasKey("prefer_digitalsfx") || ConfMan.getBool("prefer_digitalsfx"); - _useDigitalSFX = (getSciVersion() >= SCI_VERSION_2 || g_sci->getGameId() == GID_GK1 || preferDigitalSfx); + _useDigitalSFX = (getSciVersion() >= SCI_VERSION_2 || g_sci->getGameId() == GID_GK1 || ConfMan.getBool("prefer_digitalsfx")); _music = new SciMusic(_soundVersion, _useDigitalSFX); _music->init(); diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp index cd053815f0..57c1f6b48b 100644 --- a/engines/sky/control.cpp +++ b/engines/sky/control.cpp @@ -663,9 +663,8 @@ uint16 Control::doMusicSlide() { uint8 volume; while (_mouseClicked) { delay(50); - if (!_controlPanel) { + if (!_controlPanel) return 0; - } mouse = _system->getEventManager()->getMousePos(); int newY = ofsY + mouse.y; if (newY < 59) newY = 59; diff --git a/engines/sky/detection.cpp b/engines/sky/detection.cpp index 05dbe10338..dfa3ded50b 100644 --- a/engines/sky/detection.cpp +++ b/engines/sky/detection.cpp @@ -118,12 +118,18 @@ GameList SkyMetaEngine::getSupportedGames() const { const ExtraGuiOptions SkyMetaEngine::getExtraGuiOptions(const Common::String &target) const { Common::String guiOptions; + ExtraGuiOptions options; + + if (target.empty()) { + options.push_back(skyExtraGuiOption); + return options; + } + if (ConfMan.hasKey("guioptions", target)) { guiOptions = ConfMan.get("guioptions", target); guiOptions = parseGameGUIOptions(guiOptions); } - ExtraGuiOptions options; if (!guiOptions.contains(GUIO_NOSPEECH)) options.push_back(skyExtraGuiOption); return options; |