diff options
26 files changed, 347 insertions, 153 deletions
diff --git a/audio/decoders/mp3.cpp b/audio/decoders/mp3.cpp index 091f64569d..c1b3faaeb1 100644 --- a/audio/decoders/mp3.cpp +++ b/audio/decoders/mp3.cpp @@ -59,7 +59,7 @@ protected: State _state; Timestamp _length; - mad_timer_t _totalTime; + mad_timer_t _curTime; mad_stream _stream; mad_frame _frame; @@ -99,7 +99,7 @@ MP3Stream::MP3Stream(Common::SeekableReadStream *inStream, DisposeAfterUse::Flag _posInFrame(0), _state(MP3_STATE_INIT), _length(0, 1000), - _totalTime(mad_timer_zero) { + _curTime(mad_timer_zero) { // The MAD_BUFFER_GUARD must always contain zeros (the reason // for this is that the Layer III Huffman decoder of libMAD @@ -119,7 +119,7 @@ MP3Stream::MP3Stream(Common::SeekableReadStream *inStream, DisposeAfterUse::Flag // Note that we allow "MAD_ERROR_BUFLEN" as error code here, since according // to mad.h it is also set on EOF. if ((_stream.error == MAD_ERROR_NONE || _stream.error == MAD_ERROR_BUFLEN) && getRate() > 0) - _length = Timestamp(mad_timer_count(_totalTime, MAD_UNITS_MILLISECONDS), getRate()); + _length = Timestamp(mad_timer_count(_curTime, MAD_UNITS_MILLISECONDS), getRate()); deinitStream(); @@ -166,6 +166,8 @@ void MP3Stream::decodeMP3Data() { } } + // Sum up the total playback time so far + mad_timer_add(&_curTime, _frame.header.duration); // Synthesize PCM data mad_synth_frame(&_synth, &_frame); _posInFrame = 0; @@ -220,10 +222,10 @@ bool MP3Stream::seek(const Timestamp &where) { mad_timer_t destination; mad_timer_set(&destination, time / 1000, time % 1000, 1000); - if (_state != MP3_STATE_READY || mad_timer_compare(destination, _totalTime) < 0) + if (_state != MP3_STATE_READY || mad_timer_compare(destination, _curTime) < 0) initStream(); - while (mad_timer_compare(destination, _totalTime) > 0 && _state != MP3_STATE_EOS) + while (mad_timer_compare(destination, _curTime) > 0 && _state != MP3_STATE_EOS) readHeader(); decodeMP3Data(); @@ -242,7 +244,7 @@ void MP3Stream::initStream() { // Reset the stream data _inStream->seek(0, SEEK_SET); - _totalTime = mad_timer_zero; + _curTime = mad_timer_zero; _posInFrame = 0; // Update state @@ -280,7 +282,7 @@ void MP3Stream::readHeader() { } // Sum up the total playback time so far - mad_timer_add(&_totalTime, _frame.header.duration); + mad_timer_add(&_curTime, _frame.header.duration); break; } diff --git a/common/config-manager.cpp b/common/config-manager.cpp index feb3ddcf56..04b62371b2 100644 --- a/common/config-manager.cpp +++ b/common/config-manager.cpp @@ -597,7 +597,7 @@ void ConfigManager::setActiveDomain(const String &domName) { _activeDomain = 0; } else { assert(isValidDomainName(domName)); - _activeDomain = & _gameDomains[domName]; + _activeDomain = &_gameDomains[domName]; } _activeDomainName = domName; } @@ -626,6 +626,10 @@ void ConfigManager::addMiscDomain(const String &domName) { void ConfigManager::removeGameDomain(const String &domName) { assert(!domName.empty()); assert(isValidDomainName(domName)); + if (domName == _activeDomainName) { + _activeDomainName = ""; + _activeDomain = 0; + } _gameDomains.erase(domName); } @@ -638,6 +642,10 @@ void ConfigManager::removeMiscDomain(const String &domName) { void ConfigManager::renameGameDomain(const String &oldName, const String &newName) { renameDomain(oldName, newName, _gameDomains); + if (_activeDomainName == oldName) { + _activeDomainName = newName; + _activeDomain = &_gameDomains[newName]; + } } void ConfigManager::renameMiscDomain(const String &oldName, const String &newName) { diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp index fa23f5fa1a..72629a833e 100644 --- a/engines/advancedDetector.cpp +++ b/engines/advancedDetector.cpp @@ -122,7 +122,7 @@ bool cleanupPirated(ADGameDescList &matched) { // We ruled out all variants and now have nothing if (matched.empty()) { - warning("Illegitimate game copy detected. We give no support in such cases %d", matched.size()); + warning("Illegitimate game copy detected. We provide no support in such cases"); return true; } } diff --git a/engines/mads/msurface.h b/engines/mads/msurface.h index 23e0a03985..cd6bde1271 100644 --- a/engines/mads/msurface.h +++ b/engines/mads/msurface.h @@ -230,7 +230,7 @@ public: /** * Constructor */ - DepthSurface(MADSEngine *vm) : _vm(vm) {} + DepthSurface(MADSEngine *vm) : _vm(vm), _depthStyle(0) {} /** * Returns the depth at a given position diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp index d4b277d856..f3eddc3fbb 100644 --- a/engines/mads/nebular/dialogs_nebular.cpp +++ b/engines/mads/nebular/dialogs_nebular.cpp @@ -638,6 +638,7 @@ GameDialog::GameDialog(MADSEngine *vm) : FullScreenDialog(vm) { scene.clearVocab(); scene._dynamicHotspots.clear(); _vm->_dialogs->_defaultPosition = Common::Point(-1, -1); + _menuSpritesIndex = 0; } void GameDialog::display() { diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp index cb8f56bd05..98eb669616 100644 --- a/engines/mads/nebular/menu_nebular.cpp +++ b/engines/mads/nebular/menu_nebular.cpp @@ -83,6 +83,9 @@ MainMenu::MainMenu(MADSEngine *vm): MenuView(vm) { _highlightedIndex = -1; _selectedIndex = -1; _buttonDown = false; + + for (int i = 0; i < 7; ++i) + _menuItems[i] = nullptr; } MainMenu::~MainMenu() { @@ -408,7 +411,7 @@ char TextView::_resourceName[100]; void TextView::execute(MADSEngine *vm, const Common::String &resName) { assert(resName.size() < 100); - strcpy(_resourceName, resName.c_str()); + strncpy(_resourceName, resName.c_str(), sizeof(_resourceName)); vm->_dialogs->_pendingDialog = DIALOG_TEXTVIEW; } @@ -460,7 +463,7 @@ void TextView::processLines() { processCommand(); // Copy rest of line (if any) to start of buffer - strcpy(_currentLine, cEnd + 1); + strncpy(_currentLine, cEnd + 1, sizeof(_currentLine)); cStart = strchr(_currentLine, '['); } @@ -631,12 +634,13 @@ char AnimationView::_resourceName[100]; void AnimationView::execute(MADSEngine *vm, const Common::String &resName) { assert(resName.size() < 100); - strcpy(_resourceName, resName.c_str()); + strncpy(_resourceName, resName.c_str(), sizeof(_resourceName)); vm->_dialogs->_pendingDialog = DIALOG_ANIMVIEW; } AnimationView::AnimationView(MADSEngine *vm) : MenuView(vm) { _soundDriverLoaded = false; + _previousUpdate = 0; } void AnimationView::load() { diff --git a/engines/saga/shorten.cpp b/engines/saga/shorten.cpp index 426430c892..edb12a3dd9 100644 --- a/engines/saga/shorten.cpp +++ b/engines/saga/shorten.cpp @@ -29,6 +29,8 @@ // Based on etree's Shorten tool, version 3.6.1 // http://etree.org/shnutils/shorten/ +// and +// https://github.com/soiaf/Java-Shorten-decoder // FIXME: This doesn't work yet correctly @@ -154,6 +156,7 @@ uint32 ShortenGolombReader::getUint32(uint32 numBits) { byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, byte &flags) { int32 *buffer[2], *offset[2]; // up to 2 channels + int32 *oldValues[2]; byte *unpackedBuffer = 0; byte *pBuf = unpackedBuffer; int prevSize = 0; @@ -190,15 +193,18 @@ byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, by switch (type) { case kTypeS8: + mean = 0; break; case kTypeU8: flags |= Audio::FLAG_UNSIGNED; + mean = 0x80; break; case kTypeS16LH: flags |= Audio::FLAG_LITTLE_ENDIAN; // fallthrough case kTypeS16HL: flags |= Audio::FLAG_16BITS; + mean = 0; break; case kTypeU16LH: flags |= Audio::FLAG_LITTLE_ENDIAN; @@ -206,6 +212,7 @@ byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, by case kTypeU16HL: flags |= Audio::FLAG_16BITS; flags |= Audio::FLAG_UNSIGNED; + mean = 0x8000; break; case kTypeWAV: // TODO: Perhaps implement this if we find WAV Shorten encoded files @@ -264,8 +271,10 @@ byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, by for (i = 0; i < channels; i++) { buffer[i] = (int32 *)malloc((blockSize + wrap) * 4); offset[i] = (int32 *)malloc((MAX<uint32>(1, mean)) * 4); + oldValues[i] = (int32 *)malloc(64 * 4); memset(buffer[i], 0, (blockSize + wrap) * 4); memset(offset[i], 0, (MAX<uint32>(1, mean)) * 4); + memset(oldValues[i], 0, 64 * 4); } if (maxLPC > 0) @@ -329,9 +338,6 @@ byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, by channelOffset = (channelOffset >> (bitShift - 1)) >> 1; } - // FIXME: The original code in this bit tries to modify memory outside of the array (negative indices) - // in cases kCmdDiff1, kCmdDiff2 and kCmdDiff3 - // I've removed those invalid writes, since they happen all the time (even when curChannel is 0) switch (cmd) { case kCmdZero: for (i = 0; i < blockSize; i++) @@ -342,22 +348,34 @@ byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, by buffer[curChannel][i] = gReader->getSRice(energy) + channelOffset; break; case kCmdDiff1: - gReader->getSRice(energy); // i = 0 (to fix invalid table/memory access) - for (i = 1; i < blockSize; i++) - buffer[curChannel][i] = gReader->getSRice(energy) + buffer[curChannel][i - 1]; + for (i = 0; i < blockSize; i++) { + if (i == 0) + buffer[curChannel][i] = gReader->getSRice(energy) + oldValues[curChannel][0]; + else + buffer[curChannel][i] = gReader->getSRice(energy) + buffer[curChannel][i - 1]; + } break; case kCmdDiff2: - gReader->getSRice(energy); // i = 0 (to fix invalid table/memory access) - gReader->getSRice(energy); // i = 1 (to fix invalid table/memory access) - for (i = 2; i < blockSize; i++) - buffer[curChannel][i] = gReader->getSRice(energy) + 2 * buffer[curChannel][i - 1] - buffer[curChannel][i - 2]; + for (i = 0; i < blockSize; i++) { + if (i == 0) + buffer[curChannel][i] = gReader->getSRice(energy) + 2 * oldValues[curChannel][0] - oldValues[curChannel][1]; + else if (i == 1) + buffer[curChannel][i] = gReader->getSRice(energy) + 2 * buffer[curChannel][0] - oldValues[curChannel][0]; + else + buffer[curChannel][i] = gReader->getSRice(energy) + 2 * buffer[curChannel][i - 1] - buffer[curChannel][i - 2]; + } break; case kCmdDiff3: - gReader->getSRice(energy); // i = 0 (to fix invalid table/memory access) - gReader->getSRice(energy); // i = 1 (to fix invalid table/memory access) - gReader->getSRice(energy); // i = 2 (to fix invalid table/memory access) - for (i = 3; i < blockSize; i++) - buffer[curChannel][i] = gReader->getSRice(energy) + 3 * (buffer[curChannel][i - 1] - buffer[curChannel][i - 2]) + buffer[curChannel][i - 3]; + for (i = 0; i < blockSize; i++) { + if (i == 0) + buffer[curChannel][i] = gReader->getSRice(energy) + 3 * (oldValues[curChannel][0] - oldValues[curChannel][1]) + oldValues[curChannel][2]; + else if (i == 1) + buffer[curChannel][i] = gReader->getSRice(energy) + 3 * (buffer[curChannel][0] - oldValues[curChannel][0]) + oldValues[curChannel][1]; + else if (i == 2) + buffer[curChannel][i] = gReader->getSRice(energy) + 3 * (buffer[curChannel][1] - buffer[curChannel][0]) + oldValues[curChannel][0]; + else + buffer[curChannel][i] = gReader->getSRice(energy) + 3 * (buffer[curChannel][i - 1] - buffer[curChannel][i - 2]) + buffer[curChannel][i - 3]; + } break; case kCmdQLPC: lpcNum = gReader->getURice(2); @@ -417,10 +435,12 @@ byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, by // Do the wrap - // FIXME: removed for now, as this corrupts the heap, because it - // accesses negative array indices - //for (int32 k = -wrap; k < 0; k++) - // buffer[curChannel][k] = buffer[curChannel][k + blockSize]; + for (i = 0; i < 64; ++i) + oldValues[curChannel][i] = 0; + + int arrayTerminator = MIN<int>(64, blockSize); + for (i = 0; i < arrayTerminator; ++i) + oldValues[curChannel][i] = buffer[curChannel][blockSize - (i + 1)]; // Fix bitshift if (bitShift > 0) { @@ -495,6 +515,7 @@ byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, by for (i = 0; i < channels; i++) { free(buffer[i]); free(offset[i]); + free(oldValues[i]); } if (maxLPC > 0) @@ -516,6 +537,7 @@ byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, by for (i = 0; i < channels; i++) { free(buffer[i]); free(offset[i]); + free(oldValues[i]); } if (maxLPC > 0) diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index 344298ce9a..91b3c45c6e 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -2607,6 +2607,25 @@ static const struct ADGameDescription SciGameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + // Phantasmagoria - French DOS + // Supplied by Kervala in bug #6574 + {"phantasmagoria", "", { + {"resmap.001", 0, "4da82dd336d4b9cd8c16f3cc11f0c615", 11524}, + {"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 69963685}, + {"resmap.002", 0, "4f40f43f2b60bf765864433069752bb9", 12064}, + {"ressci.002", 0, "3aae6559aa1df273bc542d5ac6330d75", 78362841}, + {"resmap.003", 0, "6a392a86f14b6ddb4422978ee71e54ac", 12340}, + {"ressci.003", 0, "3aae6559aa1df273bc542d5ac6330d75", 80431189}, + {"resmap.004", 0, "df2e9462c41202de5f3843908c95a715", 12562}, + {"ressci.004", 0, "3aae6559aa1df273bc542d5ac6330d75", 82542844}, + {"resmap.005", 0, "43efd3fe834286c70a2c8b4cd747c1e2", 12616}, + {"ressci.005", 0, "3aae6559aa1df273bc542d5ac6330d75", 83790486}, + {"resmap.006", 0, "b3065e54a00190752a06dacd201b5058", 12538}, + {"ressci.006", 0, "3aae6559aa1df273bc542d5ac6330d75", 85415107}, + {"resmap.007", 0, "5633960bc106c39ca91d2d8fce18fd2d", 7984}, + AD_LISTEND}, + Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + // Phantasmagoria - English DOS Demo // Executable scanning reports "2.100.002" {"phantasmagoria", "Demo", { diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp index 31e7ca4931..be062dba64 100644 --- a/engines/sci/engine/features.cpp +++ b/engines/sci/engine/features.cpp @@ -344,9 +344,9 @@ bool GameFeatures::autoDetectGfxFunctionsType(int methodNum) { if (kFuncNum == 8) { // kDrawPic (SCI0 - SCI11) // If kDrawPic is called with 6 parameters from the overlay // selector, the game is using old graphics functions. - // Otherwise, if it's called with 8 parameters, it's using new - // graphics functions. - _gfxFunctionsType = (argc == 8) ? SCI_VERSION_0_LATE : SCI_VERSION_0_EARLY; + // Otherwise, if it's called with 8 parameters (e.g. SQ3) or 4 parameters + // (e.g. Hoyle 1/2), it's using new graphics functions. + _gfxFunctionsType = (argc == 6) ? SCI_VERSION_0_EARLY : SCI_VERSION_0_LATE; return true; } } diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index fc46d16b8d..0c2fd4e3ea 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -468,7 +468,8 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(TimesSin), SIG_EVERYWHERE, "ii", NULL, NULL }, { "SinMult", kTimesSin, SIG_EVERYWHERE, "ii", NULL, NULL }, { MAP_CALL(TimesTan), SIG_EVERYWHERE, "ii", NULL, NULL }, - { MAP_CALL(UnLoad), SIG_EVERYWHERE, "i[ri]", NULL, kUnLoad_workarounds }, + { MAP_CALL(UnLoad), SIG_EVERYWHERE, "i[ir!]", NULL, kUnLoad_workarounds }, + // ^ We allow invalid references here (e.g. bug #6600), since they will be invalidated anyway by the call itself { MAP_CALL(ValidPath), SIG_EVERYWHERE, "r", NULL, NULL }, { MAP_CALL(Wait), SIG_EVERYWHERE, "i", NULL, NULL }, diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 3738fd3dcb..58c2b8d3e3 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -371,7 +371,7 @@ void SegManager::freeHunkEntry(reg_t addr) { HunkTable *ht = (HunkTable *)getSegment(addr.getSegment(), SEG_TYPE_HUNK); if (!ht) { - warning("Attempt to free Hunk from address %04x:%04x: Invalid segment type", PRINT_REG(addr)); + warning("Attempt to free Hunk from address %04x:%04x: Invalid segment type %d", PRINT_REG(addr), getSegmentType(addr.getSegment())); return; } diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index 37e46b7a96..ea4dc2fe71 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -44,7 +44,8 @@ const SciWorkaroundEntry arithmeticWorkarounds[] = { { GID_MOTHERGOOSEHIRES,90, 90, 0, "newGameButton", "select", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_ge: MUMG Deluxe, when selecting "New Game" in the main menu. It tries to compare an integer with a list. Needs to return false for the game to continue. { GID_PHANTASMAGORIA, 902, 0, 0, "", "export 7", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_shr: when starting a chapter in Phantasmagoria { GID_QFG1VGA, 301, 928, 0, "Blink", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_div: when entering the inn, gets called with 1 parameter, but 2nd parameter is used for div which happens to be an object - { GID_QFG2, 200, 200, 0, "astro", "messages", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_lsi: when getting asked for your name by the astrologer bug #5152 + { GID_QFG2, 200, 200, 0, "astro", "messages", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_lsi: when getting asked for your name by the astrologer - bug #5152 + { GID_QFG3, 780, 999, 0, "", "export 6", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_add: trying to talk to yourself at the top of the giant tree - bug #6692 { GID_QFG4, 710,64941, 0, "RandCycle", "doit", -1, 0, { WORKAROUND_FAKE, 1 } }, // op_gt: when the tentacle appears in the third room of the caves SCI_WORKAROUNDENTRY_TERMINATOR }; diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index a322eb8e61..91b5b25e99 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -782,9 +782,13 @@ void GfxFrameout::kernelFrameout() { // TODO: For some reason, the top left nsRect coordinates get // swapped in the GK1 inventory screen, investigate why. + // This is also needed for GK1 rooms 710 and 720 (catacombs, inner and + // outer circle), for handling the tiles and talking to Wolfgang. // HACK: Fix the coordinates by explicitly setting them here. Common::Rect objNSRect = g_sci->_gfxCompare->getNSRect(itemEntry->object); - if (objNSRect.top == nsRect.left && objNSRect.left == nsRect.top && nsRect.top != 0 && nsRect.left != 0) { + uint16 roomNumber = g_sci->getEngineState()->currentRoomNumber(); + if (objNSRect.top == nsRect.left && objNSRect.left == nsRect.top && nsRect.top != 0 && nsRect.left != 0 || + (g_sci->getGameId() == GID_GK1 && (roomNumber == 710 || roomNumber == 720))) { g_sci->_gfxCompare->setNSRect(itemEntry->object, nsRect); } } diff --git a/engines/sci/parser/said.cpp b/engines/sci/parser/said.cpp index 693bbec744..27ebc58704 100644 --- a/engines/sci/parser/said.cpp +++ b/engines/sci/parser/said.cpp @@ -186,8 +186,7 @@ static bool parseList(ParseTreeNode* parentNode); static bool parseListEntry(ParseTreeNode* parentNode); static bool parseWord(ParseTreeNode* parentNode); -static bool parseWord(ParseTreeNode* parentNode) -{ +static bool parseWord(ParseTreeNode* parentNode) { int token = said_tokens[said_token]; if (token & 0x8000) return false; @@ -201,8 +200,7 @@ static bool parseWord(ParseTreeNode* parentNode) return true; } -static bool parsePart2(ParseTreeNode* parentNode, bool& nonempty) -{ +static bool parsePart2(ParseTreeNode* parentNode, bool& nonempty) { // Store current state for rolling back if we fail int curToken = said_token; int curTreePos = said_tree_pos; @@ -259,8 +257,7 @@ static bool parsePart2(ParseTreeNode* parentNode, bool& nonempty) return false; } -static bool parsePart3(ParseTreeNode* parentNode, bool& nonempty) -{ +static bool parsePart3(ParseTreeNode* parentNode, bool& nonempty) { // Store current state for rolling back if we fail int curToken = said_token; int curTreePos = said_tree_pos; @@ -318,8 +315,7 @@ static bool parsePart3(ParseTreeNode* parentNode, bool& nonempty) } -static bool parseSlash(ParseTreeNode* parentNode) -{ +static bool parseSlash(ParseTreeNode* parentNode) { // Store current state for rolling back if we fail int curToken = said_token; int curTreePos = said_tree_pos; @@ -343,8 +339,7 @@ static bool parseSlash(ParseTreeNode* parentNode) } -static bool parseRef(ParseTreeNode* parentNode) -{ +static bool parseRef(ParseTreeNode* parentNode) { // Store current state for rolling back if we fail int curToken = said_token; int curTreePos = said_tree_pos; @@ -411,8 +406,7 @@ static bool parseRef(ParseTreeNode* parentNode) return false; } -static bool parseComma(ParseTreeNode* parentNode) -{ +static bool parseComma(ParseTreeNode* parentNode) { // Store current state for rolling back if we fail int curToken = said_token; int curTreePos = said_tree_pos; @@ -435,8 +429,7 @@ static bool parseComma(ParseTreeNode* parentNode) return false; } -static bool parseListEntry(ParseTreeNode* parentNode) -{ +static bool parseListEntry(ParseTreeNode* parentNode) { // Store current state for rolling back if we fail int curToken = said_token; int curTreePos = said_tree_pos; @@ -494,8 +487,7 @@ static bool parseListEntry(ParseTreeNode* parentNode) return false; } -static bool parseList(ParseTreeNode* parentNode) -{ +static bool parseList(ParseTreeNode* parentNode) { // Store current state for rolling back if we fail int curToken = said_token; int curTreePos = said_tree_pos; @@ -524,8 +516,7 @@ static bool parseList(ParseTreeNode* parentNode) return false; } -static bool parseExpr(ParseTreeNode* parentNode) -{ +static bool parseExpr(ParseTreeNode* parentNode) { // Store current state for rolling back if we fail int curToken = said_token; int curTreePos = said_tree_pos; @@ -546,7 +537,6 @@ static bool parseExpr(ParseTreeNode* parentNode) said_attach_subtree(newParent, 0x141, 0x14F, newNode); newParent = newParent->right; - } found = parseRef(newParent); @@ -561,8 +551,7 @@ static bool parseExpr(ParseTreeNode* parentNode) return false; } -static bool parseSpec(ParseTreeNode* parentNode) -{ +static bool parseSpec(ParseTreeNode* parentNode) { // Store current state for rolling back if we fail int curToken = said_token; int curTreePos = said_tree_pos; @@ -748,9 +737,7 @@ static void node_print_desc(ParseTreeNode *) { } - -static int matchTrees(ParseTreeNode* parseT, ParseTreeNode* saidT) -{ +static int matchTrees(ParseTreeNode* parseT, ParseTreeNode* saidT) { outputDepth++; scidprintf("%*smatchTrees on ", outputDepth, ""); node_print_desc(parseT); diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp index b4a223dcff..3344b79e26 100644 --- a/engines/sci/parser/vocabulary.cpp +++ b/engines/sci/parser/vocabulary.cpp @@ -530,18 +530,19 @@ bool Vocabulary::tokenizeString(ResultWordListList &retval, const char *sentence *error = NULL; do { - c = sentence[pos_in_sentence++]; + if (Common::isAlnum(c) || (c == '-' && wordLen) || (c >= 0x80)) { currentWord[wordLen] = lowerCaseMap[c]; ++wordLen; - } - // Continue on this word */ - // Words may contain a '-', but may not - // start with one. - else { - if (wordLen) { // Finished a word? + } else if (c == '\'' && wordLen && (sentence[pos_in_sentence] == 's' || sentence[pos_in_sentence] == 'S')) { + // Skip apostrophe-s at the end of the word, if it exists + pos_in_sentence++; // skip the 's' + } else { + // Continue on this word. Words may contain a '-', but may not start with + // one. + if (wordLen) { // Finished a word? ResultWordList lookup_result; // Look it up diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp index 185ebbce6e..e546c805b5 100644 --- a/engines/scumm/charset.cpp +++ b/engines/scumm/charset.cpp @@ -253,7 +253,7 @@ CharsetRenderer::~CharsetRenderer() { CharsetRendererCommon::CharsetRendererCommon(ScummEngine *vm) : CharsetRenderer(vm), _bytesPerPixel(0), _fontHeight(0), _numChars(0) { - _shadowMode = false; + _enableShadow = false; _shadowColor = 0; } @@ -392,6 +392,10 @@ int CharsetRenderer::getStringWidth(int arg, const byte *text) { } else if (chr & 0x80) { pos++; width += _vm->_2byteWidth; + // Original keeps glyph width and character dimensions separately + if (_vm->_language == Common::KO_KOR || _vm->_language == Common::ZH_TWN) { + width++; + } continue; } } @@ -478,6 +482,12 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) { } else if (chr & 0x80) { pos++; curw += _vm->_2byteWidth; + // Original keeps glyph width and character dimensions separately + if (_vm->_language == Common::KO_KOR || _vm->_language == Common::ZH_TWN) { + curw++; + } + } else { + curw += getCharWidth(chr); } } else { curw += getCharWidth(chr); @@ -507,12 +517,17 @@ int CharsetRendererV3::getCharWidth(uint16 chr) { return spacing; } -void CharsetRendererV3::enableShadow(bool enable) { +void CharsetRendererPC::enableShadow(bool enable) { _shadowColor = 0; - _shadowMode = enable; + _enableShadow = enable; + + if (_vm->_game.version >= 7 && _vm->_language == Common::KO_KOR) + _shadowType = kHorizontalShadowType; + else + _shadowType = kNormalShadowType; } -void CharsetRendererV3::drawBits1(Graphics::Surface &dest, int x, int y, const byte *src, int drawTop, int width, int height) { +void CharsetRendererPC::drawBits1(Graphics::Surface &dest, int x, int y, const byte *src, int drawTop, int width, int height) { byte *dst = (byte *)dest.getBasePtr(x, y); byte bits = 0; @@ -525,8 +540,12 @@ void CharsetRendererV3::drawBits1(Graphics::Surface &dest, int x, int y, const b if ((x % 8) == 0) bits = *src++; if ((bits & revBitMask(x % 8)) && y + drawTop >= 0) { - if (_shadowMode) - dst[1] = dst2[0] = dst2[1] = _shadowColor; + if (_enableShadow) { + if (_shadowType == kNormalShadowType) + dst[1] = dst2[0] = dst2[1] = _shadowColor; + else if (_shadowType == kHorizontalShadowType) + dst[1] = _shadowColor; + } dst[0] = col; } dst += dest.format.bytesPerPixel; @@ -615,7 +634,7 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { if (_left + origWidth > _right + 1) return; - if (_shadowMode) { + if (_enableShadow) { width++; height++; } @@ -658,7 +677,7 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { if (_str.right < _left) { _str.right = _left; - if (_shadowMode) + if (_enableShadow) _str.right++; } @@ -776,11 +795,15 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) { printCharIntern(is2byte, _charPtr, _origWidth, _origHeight, _width, _height, vs, ignoreCharsetMask); + // Original keeps glyph width and character dimensions separately + if ((_vm->_language == Common::ZH_TWN || _vm->_language == Common::KO_KOR) && is2byte) + _origWidth++; + _left += _origWidth; if (_str.right < _left) { _str.right = _left; - if (_vm->_game.platform != Common::kPlatformFMTowns && _shadowMode) + if (_vm->_game.platform != Common::kPlatformFMTowns && _enableShadow) _str.right++; } @@ -844,7 +867,10 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr, drawTop = _top - _vm->_screenTop; } - drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight); + if (is2byte && _vm->_game.platform != Common::kPlatformFMTowns) + drawBits1(dstSurface, _left, drawTop, charPtr, drawTop, origWidth, origHeight); + else + drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight); if (_blitAlso && vs->hasTwoBuffers) { // FIXME: Revisiting this code, I think the _blitAlso mode is likely broken @@ -884,6 +910,24 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr, } bool CharsetRendererClassic::prepareDraw(uint16 chr) { + bool is2byte = (chr >= 256 && _vm->_useCJKMode); + if (is2byte) { + if (_vm->_language == Common::KO_KOR) + enableShadow(true); + + _charPtr = _vm->get2byteCharPtr(chr); + _width = _origWidth = _vm->_2byteWidth; + _height = _origHeight = _vm->_2byteHeight; + _offsX = _offsY = 0; + + if (_enableShadow) { + _width++; + _height++; + } + + return true; + } + uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); assert(charOffs < 0x14000); if (!charOffs) @@ -908,8 +952,14 @@ bool CharsetRendererClassic::prepareDraw(uint16 chr) { void CharsetRendererClassic::drawChar(int chr, Graphics::Surface &s, int x, int y) { if (!prepareDraw(chr)) return; + byte *dst = (byte *)s.getBasePtr(x, y); - drawBitsN(s, dst, _charPtr, *_fontPtr, y, _width, _height); + + bool is2byte = (_vm->_useCJKMode && chr >= 256); + if (is2byte) + drawBits1(s, x, y, _charPtr, y, _width, _height); + else + drawBitsN(s, dst, _charPtr, *_fontPtr, y, _width, _height); } void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height) { @@ -982,7 +1032,7 @@ int CharsetRendererTownsV3::getFontHeight() { void CharsetRendererTownsV3::enableShadow(bool enable) { _shadowColor = 8; - _shadowMode = enable; + _enableShadow = enable; #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE _shadowColor = 0x88; @@ -1027,13 +1077,13 @@ void CharsetRendererTownsV3::drawBits1(Graphics::Surface &dest, int x, int y, co bits = *src++; if ((bits & revBitMask(x % 8)) && y + drawTop >= 0) { if (dest.format.bytesPerPixel == 2) { - if (_shadowMode) { + if (_enableShadow) { WRITE_UINT16(dst + 2, _vm->_16BitPalette[_shadowColor]); WRITE_UINT16(dst + dest.pitch, _vm->_16BitPalette[_shadowColor]); } WRITE_UINT16(dst, _vm->_16BitPalette[_color]); } else { - if (_shadowMode) { + if (_enableShadow) { #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (scale2x) { dst[2] = dst[3] = dst2[2] = dst2[3] = _shadowColor; @@ -1124,11 +1174,11 @@ void CharsetRendererPCE::drawBits1(Graphics::Surface &dest, int x, int y, const bits = *src++; if ((bits & revBitMask(bitCount % 8)) && y + drawTop >= 0) { if (dest.format.bytesPerPixel == 2) { - if (_shadowMode) + if (_enableShadow) WRITE_UINT16(dst + dest.pitch + 2, _vm->_16BitPalette[_shadowColor]); WRITE_UINT16(dst, _vm->_16BitPalette[_color]); } else { - if (_shadowMode) + if (_enableShadow) *(dst + dest.pitch + 1) = _shadowColor; *dst = _color; } @@ -1227,7 +1277,8 @@ void CharsetRendererNut::printChar(int chr, bool ignoreCharsetMask) { int width = _current->getCharWidth(chr); int height = _current->getCharHeight(chr); - if (chr >= 256 && _vm->_useCJKMode) + bool is2byte = chr >= 256 && _vm->_useCJKMode; + if (is2byte) width = _vm->_2byteWidth; shadow.right = _left + width; @@ -1259,8 +1310,8 @@ void CharsetRendererNut::printChar(int chr, bool ignoreCharsetMask) { _str.left = _left; // Original keeps glyph width and character dimensions separately - if (_vm->_language == Common::ZH_TWN && width == 16) - width = 17; + if ((_vm->_language == Common::ZH_TWN || _vm->_language == Common::KO_KOR) && is2byte) + width++; _left += width; @@ -1327,7 +1378,7 @@ void CharsetRendererNES::printChar(int chr, bool ignoreCharsetMask) { if (_str.right < _left) { _str.right = _left; - if (_shadowMode) + if (_enableShadow) _str.right++; } @@ -1483,7 +1534,7 @@ bool CharsetRendererTownsClassic::prepareDraw(uint16 chr) { _origHeight = _height = _vm->_2byteHeight; _charPtr = _vm->get2byteCharPtr(chr); _offsX = _offsY = 0; - if (_shadowMode) { + if (_enableShadow) { _width++; _height++; } @@ -1495,7 +1546,7 @@ bool CharsetRendererTownsClassic::prepareDraw(uint16 chr) { } void CharsetRendererTownsClassic::setupShadowMode() { - _shadowMode = true; + _enableShadow = true; _shadowColor = _vm->_townsCharsetColorMap[0]; assert(_vm->_cjkFont); diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h index 5a9977b7d6..b4b3d88ccd 100644 --- a/engines/scumm/charset.h +++ b/engines/scumm/charset.h @@ -100,7 +100,7 @@ protected: int _numChars; byte _shadowColor; - bool _shadowMode; + bool _enableShadow; public: CharsetRendererCommon(ScummEngine *vm); @@ -110,7 +110,24 @@ public: virtual int getFontHeight(); }; -class CharsetRendererClassic : public CharsetRendererCommon { +class CharsetRendererPC : public CharsetRendererCommon { + enum ShadowType { + kNoShadowType, + kNormalShadowType, + kHorizontalShadowType + }; + + ShadowType _shadowType; + +protected: + virtual void enableShadow(bool enable); + virtual void drawBits1(Graphics::Surface &dest, int x, int y, const byte *src, int drawTop, int width, int height); + +public: + CharsetRendererPC(ScummEngine *vm) : CharsetRendererCommon(vm), _shadowType(kNoShadowType) { } +}; + +class CharsetRendererClassic : public CharsetRendererPC { protected: virtual void drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height); void printCharIntern(bool is2byte, const byte *charPtr, int origWidth, int origHeight, int width, int height, VirtScreen *vs, bool ignoreCharsetMask); @@ -124,7 +141,7 @@ protected: VirtScreenNumber _drawScreen; public: - CharsetRendererClassic(ScummEngine *vm) : CharsetRendererCommon(vm) {} + CharsetRendererClassic(ScummEngine *vm) : CharsetRendererPC(vm) {} void printChar(int chr, bool ignoreCharsetMask); void drawChar(int chr, Graphics::Surface &s, int x, int y); @@ -170,10 +187,8 @@ public: int getCharWidth(uint16 chr) { return 8; } }; -class CharsetRendererV3 : public CharsetRendererCommon { +class CharsetRendererV3 : public CharsetRendererPC { protected: - virtual void enableShadow(bool enable); - virtual void drawBits1(Graphics::Surface &dest, int x, int y, const byte *src, int drawTop, int width, int height); virtual int getDrawWidthIntern(uint16 chr); virtual int getDrawHeightIntern(uint16 chr); virtual void setDrawCharIntern(uint16 chr) {} @@ -181,7 +196,7 @@ protected: const byte *_widthTable; public: - CharsetRendererV3(ScummEngine *vm) : CharsetRendererCommon(vm) {} + CharsetRendererV3(ScummEngine *vm) : CharsetRendererPC(vm) {} void printChar(int chr, bool ignoreCharsetMask); void drawChar(int chr, Graphics::Surface &s, int x, int y); diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp index 5e2566dc32..824dfec144 100644 --- a/engines/scumm/input.cpp +++ b/engines/scumm/input.cpp @@ -435,8 +435,9 @@ void ScummEngine_v6::processKeyboard(Common::KeyState lastKeyHit) { break; } - if (VAR_VOICE_MODE != 0xFF) - VAR(VAR_VOICE_MODE) = _voiceMode; + // We need to sync the current sound settings here to make sure that + // we actually update the mute state of speech properly. + syncSoundSettings(); return; } diff --git a/engines/scumm/nut_renderer.cpp b/engines/scumm/nut_renderer.cpp index 1d5761ef48..d8672c473c 100644 --- a/engines/scumm/nut_renderer.cpp +++ b/engines/scumm/nut_renderer.cpp @@ -395,10 +395,6 @@ void NutRenderer::drawChar(const Graphics::Surface &s, byte c, int x, int y, byt } void NutRenderer::draw2byte(const Graphics::Surface &s, int c, int x, int y, byte color) { - // FIXME: This gets passed a const destination Surface. Intuitively this - // should never get written to. But sadly it does... For now we simply - // cast the const qualifier away. - byte *dst = (byte *)const_cast<void *>(s.getBasePtr(x, y)); const int width = _vm->_2byteWidth; const int height = MIN(_vm->_2byteHeight, s.h - y); const byte *src = _vm->get2byteCharPtr(c); @@ -408,17 +404,50 @@ void NutRenderer::draw2byte(const Graphics::Surface &s, int c, int x, int y, byt return; } - for (int ty = 0; ty < height; ty++) { - for (int tx = 0; tx < width; tx++) { - if ((tx & 7) == 0) - bits = *src++; - if (x + tx < 0 || x + tx >= s.w || y + ty < 0) - continue; - if (bits & revBitMask(tx % 8)) { - dst[tx] = color; + enum ShadowMode { + kNone, + kKoreanV8ShadowMode + }; + + ShadowMode shadowMode = kNone; + + if (_vm->_language == Common::KO_KOR && _vm->_game.version == 8) { + shadowMode = kKoreanV8ShadowMode; + } + + int shadowOffsetXTable[4] = {-1, 0, 1, 0}; + int shadowOffsetYTable[4] = {0, 1, 0, 0}; + int shadowOffsetColorTable[4] = {0, 0, 0, color}; + + int shadowIdx = 3; + if (shadowMode == kKoreanV8ShadowMode) + shadowIdx = 0; + + const byte *origSrc = src; + + for (; shadowIdx < 4; shadowIdx++) { + int offX = x + shadowOffsetXTable[shadowIdx]; + int offY = y + shadowOffsetYTable[shadowIdx]; + byte drawColor = shadowOffsetColorTable[shadowIdx]; + + // FIXME: This gets passed a const destination Surface. Intuitively this + // should never get written to. But sadly it does... For now we simply + // cast the const qualifier away. + byte *dst = (byte *)const_cast<void *>(s.getBasePtr(offX, offY)); + src = origSrc; + + for (int ty = 0; ty < height; ty++) { + for (int tx = 0; tx < width; tx++) { + if ((tx & 7) == 0) + bits = *src++; + if (offX + tx < 0 || offX + tx >= s.w || offY + ty < 0) + continue; + if (bits & revBitMask(tx % 8)) { + dst[tx] = drawColor; + } } + dst += s.pitch; } - dst += s.pitch; } } diff --git a/engines/scumm/smush/smush_font.cpp b/engines/scumm/smush/smush_font.cpp index 4c04901b42..e2f75a6862 100644 --- a/engines/scumm/smush/smush_font.cpp +++ b/engines/scumm/smush/smush_font.cpp @@ -115,9 +115,7 @@ int SmushFont::drawChar(byte *buffer, int dst_width, int x, int y, byte chr) { int SmushFont::draw2byte(byte *buffer, int dst_width, int x, int y, int idx) { int w = _vm->_2byteWidth; int h = _vm->_2byteHeight; - - byte *src = _vm->get2byteCharPtr(idx); - byte *dst = buffer + dst_width * (y + (_vm->_game.id == GID_CMI ? 7 : (_vm->_game.id == GID_DIG ? 2 : 0))) + x; + const byte *src = _vm->get2byteCharPtr(idx); byte bits = 0; char color = (_color != -1) ? _color : 1; @@ -128,18 +126,60 @@ int SmushFont::draw2byte(byte *buffer, int dst_width, int x, int y, int idx) { if (_vm->_game.id == GID_FT) color = 1; - for (int j = 0; j < h; j++) { - for (int i = 0; i < w; i++) { - if ((i % 8) == 0) - bits = *src++; - if (bits & revBitMask(i % 8)) { - dst[i + 1] = 0; - dst[dst_width + i] = 0; - dst[dst_width + i + 1] = 0; - dst[i] = color; + enum ShadowMode { + kNone, + kNormalShadowMode, + kKoreanV7ShadowMode, + kKoreanV8ShadowMode + }; + + ShadowMode shadowMode = kNone; + + if (_vm->_language == Common::KO_KOR) { + if (_vm->_game.version == 8) + shadowMode = kKoreanV8ShadowMode; + else + shadowMode = kKoreanV7ShadowMode; + } + + int shadowOffsetXTable[4] = {-1, 0, 1, 0}; + int shadowOffsetYTable[4] = {0, 1, 0, 0}; + int shadowOffsetColorTable[4] = {0, 0, 0, color}; + + int shadowIdx = 3; + if (shadowMode == kKoreanV8ShadowMode) + shadowIdx = 0; + else if (shadowMode == kKoreanV7ShadowMode) + shadowIdx = 2; + + const byte *origSrc = src; + + for (; shadowIdx < 4; shadowIdx++) { + int offX = x + shadowOffsetXTable[shadowIdx]; + int offY = y + shadowOffsetYTable[shadowIdx]; + byte drawColor = shadowOffsetColorTable[shadowIdx]; + + src = origSrc; + + byte *dst = buffer + dst_width * (offY + (_vm->_game.id == GID_CMI ? 7 : (_vm->_game.id == GID_DIG ? 2 : 0))) + offX; + + for (int j = 0; j < h; j++) { + for (int i = 0; i < w; i++) { + if (offX + i < 0) + continue; + if ((i % 8) == 0) + bits = *src++; + if (bits & revBitMask(i % 8)) { + if (shadowMode == kNormalShadowMode) { + dst[i + 1] = 0; + dst[dst_width + i] = 0; + dst[dst_width + i + 1] = 0; + } + dst[i] = drawColor; + } } + dst += dst_width; } - dst += dst_width; } return w + 1; } diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index 7f045517bc..cb428d1c15 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -658,7 +658,11 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle _vm->_imuseDigital->startVoice(kTalkSoundID, input); #endif } else { - _mixer->playStream(Audio::Mixer::kSpeechSoundType, handle, input, id); + if (mode == 1) { + _mixer->playStream(Audio::Mixer::kSFXSoundType, handle, input, id); + } else { + _mixer->playStream(Audio::Mixer::kSpeechSoundType, handle, input, id); + } } } } @@ -847,9 +851,6 @@ void Sound::soundKludge(int *list, int num) { } void Sound::talkSound(uint32 a, uint32 b, int mode, int channel) { - if (_vm->_game.version >= 5 && ConfMan.getBool("speech_mute")) - return; - if (mode == 1) { _talk_sound_a1 = a; _talk_sound_b1 = b; diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp index b6c7ad3d2b..e8f08bcc61 100644 --- a/engines/toltecs/detection.cpp +++ b/engines/toltecs/detection.cpp @@ -86,6 +86,20 @@ static const ToltecsGameDescription gameDescriptions[] = { }, { + // 3 Skulls of the Toltecs PIRATE CD-RIP version (no audio) + // == DO NOT RE-ADD == + { + "toltecs", + 0, + AD_ENTRY1s("WESTERN", "56d0da91ec3db8ac869594357584e851", 104804435), + Common::EN_ANY, + Common::kPlatformDOS, + ADGF_PIRATED, + GUIO1(GUIO_NONE) + }, + }, + + { // 3 Skulls of the Toltecs Russian version { "toltecs", diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 14e7d104d2..2f5051c157 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -2037,23 +2037,19 @@ int32 ToonEngine::characterTalk(int32 dialogid, bool blocking) { } } - int32 myId = 0; char *myLine; - if (dialogid < 1000) { + if (dialogid < 1000) myLine = _roomTexts->getText(dialogid); - myId = dialogid; - } else { + else myLine = _genericTexts->getText(dialogid - 1000); - myId = dialogid - 1000; - } if (!myLine) return 0; bool oldMouseHidden = _gameState->_mouseHidden; - if (blocking) { + if (blocking) _gameState->_mouseHidden = true; - } + // get what is before the string int a = READ_LE_UINT16(myLine - 2); @@ -2090,10 +2086,8 @@ int32 ToonEngine::characterTalk(int32 dialogid, bool blocking) { while ((waitChar->getAnimFlag() & 0x10) == 0x10 && !_shouldQuit) doFrame(); } - } else { - if (_audioManager->voiceStillPlaying()) - _audioManager->stopCurrentVoice(); - } + } else if (_audioManager->voiceStillPlaying()) + _audioManager->stopCurrentVoice(); for (int32 i = 0; i < numParticipants - 1; i++) { // listener @@ -2133,10 +2127,10 @@ int32 ToonEngine::characterTalk(int32 dialogid, bool blocking) { getTextPosition(talkerId, &_currentTextLineX, &_currentTextLineY); if (dialogid < 1000) { - myId = _roomTexts->getId(dialogid); + int myId = _roomTexts->getId(dialogid); _audioManager->playVoice(myId, false); } else { - myId = _genericTexts->getId(dialogid - 1000); + int myId = _genericTexts->getId(dialogid - 1000); _audioManager->playVoice(myId, true); } diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp index e854378ae4..517278e155 100644 --- a/engines/zvision/scripting/actions.cpp +++ b/engines/zvision/scripting/actions.cpp @@ -155,7 +155,7 @@ bool ActionEnableControl::execute(ZVision *engine) { ActionMusic::ActionMusic(const Common::String &line) : _volume(255) { uint type; - char fileNameBuffer[25]; + char fileNameBuffer[26]; uint loop; uint volume = 255; @@ -211,7 +211,7 @@ bool ActionMusic::execute(ZVision *engine) { ////////////////////////////////////////////////////////////////////////////// ActionPreloadAnimation::ActionPreloadAnimation(const Common::String &line) { - char fileName[25]; + char fileName[26]; // The two %*u are always 0 and dont seem to have a use sscanf(line.c_str(), "%*[^:]:%*[^:]:%u(%25s %*u %*u %u %u)", &_key, fileName, &_mask, &_framerate); @@ -238,7 +238,7 @@ bool ActionPreloadAnimation::execute(ZVision *engine) { ////////////////////////////////////////////////////////////////////////////// ActionPlayAnimation::ActionPlayAnimation(const Common::String &line) { - char fileName[25]; + char fileName[26]; // The two %*u are always 0 and dont seem to have a use sscanf(line.c_str(), @@ -312,7 +312,7 @@ bool ActionRandom::execute(ZVision *engine) { ////////////////////////////////////////////////////////////////////////////// ActionSetPartialScreen::ActionSetPartialScreen(const Common::String &line) { - char fileName[25]; + char fileName[26]; uint color; sscanf(line.c_str(), "%*[^(](%u %u %25s %*u %u)", &_x, &_y, fileName, &color); @@ -342,7 +342,7 @@ bool ActionSetPartialScreen::execute(ZVision *engine) { ////////////////////////////////////////////////////////////////////////////// ActionSetScreen::ActionSetScreen(const Common::String &line) { - char fileName[25]; + char fileName[26]; sscanf(line.c_str(), "%*[^(](%25[^)])", fileName); _fileName = Common::String(fileName); @@ -360,7 +360,7 @@ bool ActionSetScreen::execute(ZVision *engine) { ////////////////////////////////////////////////////////////////////////////// ActionStreamVideo::ActionStreamVideo(const Common::String &line) { - char fileName[25]; + char fileName[26]; uint skippable; sscanf(line.c_str(), "%*[^(](%25s %u %u %u %u %u %u)", fileName, &_x1, &_y1, &_x2, &_y2, &_flags, &skippable); diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp index 5cf5086691..a35548d02e 100644 --- a/engines/zvision/scripting/controls/input_control.cpp +++ b/engines/zvision/scripting/controls/input_control.cpp @@ -75,7 +75,7 @@ InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStre } else if (line.matchString("*next_tabstop*", true)) { sscanf(line.c_str(), "%*[^(](%u)", &_nextTabstop); } else if (line.matchString("*cursor_animation*", true)) { - char fileName[25]; + char fileName[26]; sscanf(line.c_str(), "%*[^(](%25s %*u)", fileName); diff --git a/test/common/rendermode.h b/test/common/rendermode.h index e5e277f16b..b96ae243a5 100644 --- a/test/common/rendermode.h +++ b/test/common/rendermode.h @@ -49,7 +49,6 @@ class RenderModeTestSuite : public CxxTest::TestSuite { * Notably, the output should not be in mixed case. */ TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("FMTOWNS")), "fmtowns", 7); - TS_ASSERT_DIFFERS(Common::getRenderModeCode(Common::parseRenderMode("FMTOWNS")), "fmtowns"); TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("CGA")), "cga", 3); TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("vga")), "vga", 3); TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("Ega")), "ega", 3); |