aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--audio/decoders/qdm2.cpp104
-rw-r--r--base/main.cpp4
-rw-r--r--common/quicktime.cpp15
-rw-r--r--common/quicktime.h36
-rw-r--r--engines/advancedDetector.cpp13
-rw-r--r--engines/agos/script_s1.cpp6
-rw-r--r--engines/gob/detection_tables.h14
-rw-r--r--engines/metaengine.h9
-rw-r--r--engines/queen/queen.cpp8
-rw-r--r--engines/sci/engine/features.cpp2
-rw-r--r--engines/sci/engine/workarounds.cpp2
-rw-r--r--engines/sci/sound/soundcmd.cpp5
-rw-r--r--engines/sky/control.cpp3
-rw-r--r--engines/sky/detection.cpp8
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;