[Scummvm-git-logs] scummvm master -> 9d62caa684feb2e403783a0b8f1fd11a1457436d

csnover csnover at users.noreply.github.com
Tue Jul 18 06:56:53 CEST 2017


This automated email contains information about 7 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
2528ecf26e SCI32: Fix playback of looped audio
afe344cc1f SCI32: Add guest additions support for LSL7
09ef11a8cb SCI32: Remove ENABLE_SCI3_GAMES ifdef, now that they are supported
ba4fccdb26 SCI32: Add workaround for Torin/LSL7 running with subtitles only
64d090dcb8 SCI32: Fix stream leaks in Audio32/SOLStream
dcb6c32215 SCI32: Destroy audio streams in Audio32 using DisposeAfterUse flag
9d62caa684 SCI32: Promote LSL7 to ADGF_TESTING


Commit: 2528ecf26e0b3767aca53019262d0c133827ddbb
    https://github.com/scummvm/scummvm/commit/2528ecf26e0b3767aca53019262d0c133827ddbb
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-07-17T22:42:18-05:00

Commit Message:
SCI32: Fix playback of looped audio

This fixes at least Lighthouse audio 808 in room 270, and audio
801 in room 810.

Changed paths:
    engines/sci/sound/audio32.cpp
    engines/sci/sound/audio32.h


diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp
index cfbab8b..0bef60b 100644
--- a/engines/sci/sound/audio32.cpp
+++ b/engines/sci/sound/audio32.cpp
@@ -46,6 +46,64 @@
 
 namespace Sci {
 
+class MutableLoopAudioStream : public Audio::AudioStream {
+public:
+	MutableLoopAudioStream(Audio::RewindableAudioStream *stream, const bool loop_, const DisposeAfterUse::Flag dispose = DisposeAfterUse::YES) :
+		_stream(stream, dispose),
+		_loop(loop_) {}
+
+	virtual int readBuffer(int16 *buffer, int numSamples) override {
+		int totalSamplesRead = 0;
+		int samplesRead;
+		do {
+			if (_loop && _stream->endOfStream()) {
+				_stream->rewind();
+			}
+
+			samplesRead = _stream->readBuffer(buffer, numSamples);
+			totalSamplesRead += samplesRead;
+			numSamples -= samplesRead;
+		} while (samplesRead > 0 && _loop && numSamples > 0);
+		return totalSamplesRead;
+	}
+
+	virtual bool isStereo() const override {
+		return _stream->isStereo();
+	}
+
+	virtual int getRate() const override {
+		return _stream->getRate();
+	}
+
+	virtual bool endOfData() const override {
+		return !_loop && _stream->endOfData();
+	}
+
+	virtual bool endOfStream() const override {
+		return !_loop && _stream->endOfStream();
+	}
+
+	bool &loop() {
+		return _loop;
+	}
+
+	bool loop() const {
+		return _loop;
+	}
+
+	virtual Audio::Timestamp getLength() const {
+		Audio::SeekableAudioStream *stream = dynamic_cast<Audio::SeekableAudioStream *>(_stream.get());
+		if (stream == nullptr) {
+			error("Cannot get length from a non-seekable stream");
+		}
+		return stream->getLength();
+	}
+
+private:
+	Common::DisposablePtr<Audio::RewindableAudioStream> _stream;
+	bool _loop;
+};
+
 bool detectSolAudio(Common::SeekableReadStream &stream) {
 	const size_t initialPosition = stream.pos();
 
@@ -138,43 +196,10 @@ Audio32::~Audio32() {
 #pragma mark -
 #pragma mark AudioStream implementation
 
-int Audio32::writeAudioInternal(Audio::AudioStream *const sourceStream, Audio::RateConverter *const converter, Audio::st_sample_t *targetBuffer, const int numSamples, const Audio::st_volume_t leftVolume, const Audio::st_volume_t rightVolume, const bool loop) {
-	int samplesToRead = numSamples;
-
-	// The parent rate converter will request N * 2
-	// samples from this `readBuffer` call, because
-	// we tell it that we send stereo output, but
-	// the source stream we're mixing in may be
-	// mono, in which case we need to request half
-	// as many samples from the mono stream and let
-	// the converter double them for stereo output
-	samplesToRead >>= 1;
-
-	int samplesWritten = 0;
-
-	do {
-		if (loop && sourceStream->endOfStream()) {
-			Audio::RewindableAudioStream *rewindableStream = dynamic_cast<Audio::RewindableAudioStream *>(sourceStream);
-			if (rewindableStream == nullptr) {
-				error("[Audio32::writeAudioInternal]: Unable to cast stream");
-			}
-			rewindableStream->rewind();
-		}
-
-		const int loopSamplesWritten = converter->flow(*sourceStream, targetBuffer, samplesToRead, leftVolume, rightVolume);
-
-		if (loopSamplesWritten == 0) {
-			break;
-		}
-
-		samplesToRead -= loopSamplesWritten;
-		samplesWritten += loopSamplesWritten;
-		targetBuffer += loopSamplesWritten << (sourceStream->isStereo() ? 0 : 1);
-	} while (loop && samplesToRead > 0);
-
-	samplesWritten <<= 1;
-
-	return samplesWritten;
+int Audio32::writeAudioInternal(Audio::AudioStream *const sourceStream, Audio::RateConverter *const converter, Audio::st_sample_t *targetBuffer, const int numSamples, const Audio::st_volume_t leftVolume, const Audio::st_volume_t rightVolume) {
+	const int samplePairsToRead = numSamples >> 1;
+	const int samplePairsWritten = converter->flow(*sourceStream, targetBuffer, samplePairsToRead, leftVolume, rightVolume);
+	return samplePairsWritten << 1;
 }
 
 int16 Audio32::getNumChannelsToMix() const {
@@ -357,7 +382,7 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
 
 			memset(_monitoredBuffer, 0, _monitoredBufferSize);
 
-			_numMonitoredSamples = writeAudioInternal(channel.stream, channel.converter, _monitoredBuffer, numSamples, leftVolume, rightVolume, channel.loop);
+			_numMonitoredSamples = writeAudioInternal(channel.stream, channel.converter, _monitoredBuffer, numSamples, leftVolume, rightVolume);
 
 			Audio::st_sample_t *sourceBuffer = _monitoredBuffer;
 			Audio::st_sample_t *targetBuffer = buffer;
@@ -369,7 +394,7 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
 			if (_numMonitoredSamples > maxSamplesWritten) {
 				maxSamplesWritten = _numMonitoredSamples;
 			}
-		} else if (!channel.stream->endOfStream() || channel.loop) {
+		} else if (!channel.stream->endOfStream()) {
 			if (playOnlyMonitoredChannel) {
 				// Audio that is not on the monitored channel is silent
 				// when the monitored channel is active, but the stream still
@@ -380,7 +405,7 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
 				leftVolume = rightVolume = 0;
 			}
 
-			const int channelSamplesWritten = writeAudioInternal(channel.stream, channel.converter, buffer, numSamples, leftVolume, rightVolume, channel.loop);
+			const int channelSamplesWritten = writeAudioInternal(channel.stream, channel.converter, buffer, numSamples, leftVolume, rightVolume);
 			if (channelSamplesWritten > maxSamplesWritten) {
 				maxSamplesWritten = channelSamplesWritten;
 			}
@@ -495,15 +520,7 @@ void Audio32::freeUnusedChannels() {
 	for (int16 channelIndex = 0; channelIndex < _numActiveChannels; ++channelIndex) {
 		const AudioChannel &channel = getChannel(channelIndex);
 		if (!channel.robot && channel.stream->endOfStream()) {
-			if (channel.loop) {
-				Audio::SeekableAudioStream *stream = dynamic_cast<Audio::SeekableAudioStream *>(channel.stream);
-				if (stream == nullptr) {
-					error("[Audio32::freeUnusedChannels]: Unable to cast stream for resource %s", channel.id.toString().c_str());
-				}
-				stream->rewind();
-			} else {
-				stop(channelIndex--);
-			}
+			stop(channelIndex--);
 		}
 	}
 
@@ -634,7 +651,6 @@ bool Audio32::playRobotAudio(const RobotAudioStream::RobotAudioPacket &packet) {
 	if (isNewChannel) {
 		channel.id = ResourceId();
 		channel.resource = nullptr;
-		channel.loop = false;
 		channel.robot = true;
 		channel.fadeStartTick = 0;
 		channel.pausedAtTick = 0;
@@ -704,7 +720,7 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 
 	if (channelIndex != kNoExistingChannel) {
 		AudioChannel &channel = getChannel(channelIndex);
-		Audio::SeekableAudioStream *stream = dynamic_cast<Audio::SeekableAudioStream *>(channel.stream);
+		MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream);
 		if (stream == nullptr) {
 			error("[Audio32::play]: Unable to cast stream for resource %s", resourceId.toString().c_str());
 		}
@@ -770,7 +786,6 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 	AudioChannel &channel = getChannel(channelIndex);
 	channel.id = resourceId;
 	channel.resource = resource;
-	channel.loop = loop;
 	channel.robot = false;
 	channel.fadeStartTick = 0;
 	channel.soundNode = soundNode;
@@ -784,10 +799,12 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 
 	Common::SeekableReadStream *dataStream = channel.resourceStream = resource->makeStream();
 
+	Audio::RewindableAudioStream *audioStream;
+
 	if (detectSolAudio(*dataStream)) {
-		channel.stream = makeSOLStream(dataStream, DisposeAfterUse::NO);
+		audioStream = makeSOLStream(dataStream, DisposeAfterUse::NO);
 	} else if (detectWaveAudio(*dataStream)) {
-		channel.stream = Audio::makeWAVStream(dataStream, DisposeAfterUse::NO);
+		audioStream = Audio::makeWAVStream(dataStream, DisposeAfterUse::NO);
 	} else {
 		byte flags = Audio::FLAG_LITTLE_ENDIAN;
 		if (_globalBitDepth == 16) {
@@ -800,9 +817,10 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 			flags |= Audio::FLAG_STEREO;
 		}
 
-		channel.stream = Audio::makeRawStream(dataStream, _globalSampleRate, flags, DisposeAfterUse::NO);
+		audioStream = Audio::makeRawStream(dataStream, _globalSampleRate, flags, DisposeAfterUse::NO);
 	}
 
+	channel.stream = new MutableLoopAudioStream(audioStream, loop);
 	channel.converter = Audio::makeRateConverter(channel.stream->getRate(), getRate(), channel.stream->isStereo(), false);
 
 	// NOTE: SCI engine sets up a decompression buffer here for the audio
@@ -813,7 +831,7 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 	// use audio streams, and allocate and fill the monitoring buffer
 	// when reading audio data from the stream.
 
-	Audio::SeekableAudioStream *stream = dynamic_cast<Audio::SeekableAudioStream *>(channel.stream);
+	MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream);
 	if (stream == nullptr) {
 		error("[Audio32::play]: Unable to cast stream for resource %s", resourceId.toString().c_str());
 	}
@@ -994,7 +1012,10 @@ void Audio32::setLoop(const int16 channelIndex, const bool loop) {
 	}
 
 	AudioChannel &channel = getChannel(channelIndex);
-	channel.loop = loop;
+
+	MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream);
+	assert(stream);
+	stream->loop() = loop;
 }
 
 #pragma mark -
@@ -1259,6 +1280,7 @@ void Audio32::printAudioList(Console *con) const {
 	Common::StackLock lock(_mutex);
 	for (int i = 0; i < _numActiveChannels; ++i) {
 		const AudioChannel &channel = _channels[i];
+		const MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream);
 		con->debugPrintf("  %d[%04x:%04x]: %s, started at %d, pos %d/%d, vol %d, pan %d%s%s\n",
 						 i,
 						 PRINT_REG(channel.soundNode),
@@ -1268,7 +1290,7 @@ void Audio32::printAudioList(Console *con) const {
 						 channel.duration,
 						 channel.volume,
 						 channel.pan,
-						 channel.loop ? ", looping" : "",
+						 stream && stream->loop() ? ", looping" : "",
 						 channel.pausedAtTick ? ", paused" : "");
 		if (channel.fadeStartTick) {
 			con->debugPrintf("                fade: vol %d -> %d, started at %d, pos %d/%d%s\n",
diff --git a/engines/sci/sound/audio32.h b/engines/sci/sound/audio32.h
index 510fbc1..59f96a8 100644
--- a/engines/sci/sound/audio32.h
+++ b/engines/sci/sound/audio32.h
@@ -85,12 +85,6 @@ struct AudioChannel {
 	uint32 pausedAtTick;
 
 	/**
-	 * Whether or not the audio in this channel should loop
-	 * infinitely.
-	 */
-	bool loop;
-
-	/**
 	 * The time, in ticks, that the channel fade began.
 	 * If 0, the channel is not being faded.
 	 */
@@ -205,7 +199,7 @@ private:
 	 * Mixes audio from the given source stream into the
 	 * target buffer using the given rate converter.
 	 */
-	int writeAudioInternal(Audio::AudioStream *const sourceStream, Audio::RateConverter *const converter, Audio::st_sample_t *targetBuffer, const int numSamples, const Audio::st_volume_t leftVolume, const Audio::st_volume_t rightVolume, const bool loop);
+	int writeAudioInternal(Audio::AudioStream *const sourceStream, Audio::RateConverter *const converter, Audio::st_sample_t *targetBuffer, const int numSamples, const Audio::st_volume_t leftVolume, const Audio::st_volume_t rightVolume);
 
 #pragma mark -
 #pragma mark Channel management


Commit: afe344cc1f001bffc40f04f9b14f8af8b2c5349c
    https://github.com/scummvm/scummvm/commit/afe344cc1f001bffc40f04f9b14f8af8b2c5349c
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-07-17T22:42:18-05:00

Commit Message:
SCI32: Add guest additions support for LSL7

Changed paths:
    engines/sci/engine/features.cpp
    engines/sci/engine/guest_additions.cpp
    engines/sci/engine/script_patches.cpp
    engines/sci/engine/selector.cpp
    engines/sci/engine/selector.h


diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp
index bddcac9..e64cf9c 100644
--- a/engines/sci/engine/features.cpp
+++ b/engines/sci/engine/features.cpp
@@ -556,6 +556,7 @@ bool GameFeatures::supportsSpeechWithSubtitles() const {
 	case GID_GK1:
 	case GID_KQ7:
 	case GID_LSL6HIRES:
+	case GID_LSL7:
 	case GID_PQ4:
 	case GID_QFG4:
 	case GID_SQ6:
@@ -573,6 +574,7 @@ bool GameFeatures::audioVolumeSyncUsesGlobals() const {
 	case GID_GK1:
 	case GID_GK2:
 	case GID_LSL6HIRES:
+	case GID_LSL7:
 	case GID_PHANTASMAGORIA:
 	case GID_TORIN:
 		// TODO: SCI3
@@ -600,6 +602,7 @@ MessageTypeSyncStrategy GameFeatures::getMessageTypeSyncStrategy() const {
 		return g_sci->isCD() ? kMessageTypeSyncStrategyDefault : kMessageTypeSyncStrategyNone;
 
 	case GID_KQ7:
+	case GID_LSL7:
 	case GID_MOTHERGOOSEHIRES:
 	case GID_PHANTASMAGORIA:
 	case GID_SQ6:
diff --git a/engines/sci/engine/guest_additions.cpp b/engines/sci/engine/guest_additions.cpp
index 873152b..2cfed13 100644
--- a/engines/sci/engine/guest_additions.cpp
+++ b/engines/sci/engine/guest_additions.cpp
@@ -141,9 +141,9 @@ bool GuestAdditions::shouldSyncAudioToScummVM() const {
 													objName == "dacVolDown" ||
 													objName == "dacVolUp")) {
 			return true;
-		} else if (gameId == GID_TORIN && (objName == "oMusicScroll" ||
-										   objName == "oSFXScroll" ||
-										   objName == "oAudioScroll")) {
+		} else if ((gameId == GID_LSL7 || gameId == GID_TORIN) && (objName == "oMusicScroll" ||
+																   objName == "oSFXScroll" ||
+																   objName == "oAudioScroll")) {
 			return true;
 #endif
 		}
@@ -227,7 +227,9 @@ void GuestAdditions::instantiateScriptHook(Script &script, const bool ignoreDela
 		return;
 	}
 
-	if (g_sci->getGameId() == GID_TORIN && script.getScriptNumber() == 64866) {
+	if ((g_sci->getGameId() == GID_LSL7 || g_sci->getGameId() == GID_TORIN) &&
+		script.getScriptNumber() == 64866) {
+
 		patchGameSaveRestoreTorin(script);
 	} else if (script.getScriptNumber() == 64990) {
 		// 64990 is the system script containing SRDialog. This script is used
@@ -381,9 +383,9 @@ void GuestAdditions::patchGameSaveRestoreSCI32(Script &script) const {
 }
 
 static const byte SRTorinPatch[] = {
-	0x38, 0x8d, 0x00,                     // pushi $8d (new)
+	0x38, 0xFF, 0xFF,                     // pushi new
 	0x76,                                 // push0
-	0x51, 0x0f,                           // class $f (Str)
+	0x51, 0x0f,                           // class Str
 	0x4a, 0x04, 0x00,                     // send 4
 	0xa3, 0x01,                           // sal 1
 	0x76,                                 // push0
@@ -396,6 +398,12 @@ void GuestAdditions::patchGameSaveRestoreTorin(Script &script) const {
 	const uint32 address = script.validateExportFunc(2, true);
 	byte *patchPtr = const_cast<byte *>(script.getBuf(address));
 	memcpy(patchPtr, SRTorinPatch, sizeof(SRTorinPatch));
+
+	const Selector newSelector = SELECTOR(new_);
+	assert(newSelector != -1);
+	patchPtr[1] = newSelector & 0xFF;
+	patchPtr[2] = (newSelector >> 8) & 0xFF;
+
 	if (g_sci->isBE()) {
 		SWAP(patchPtr[1], patchPtr[2]);
 		SWAP(patchPtr[8], patchPtr[9]);
@@ -403,7 +411,7 @@ void GuestAdditions::patchGameSaveRestoreTorin(Script &script) const {
 }
 
 reg_t GuestAdditions::kScummVMSaveLoad(EngineState *s, int argc, reg_t *argv) const {
-	if (g_sci->getGameId() == GID_TORIN) {
+	if (g_sci->getGameId() == GID_LSL7 || g_sci->getGameId() == GID_TORIN) {
 		return promptSaveRestoreTorin(s, argc, argv);
 	}
 
@@ -811,6 +819,7 @@ void GuestAdditions::syncAudioVolumeGlobalsFromScummVM() const {
 		break;
 	}
 
+	case GID_LSL7:
 	case GID_TORIN: {
 		const int16 musicVolume  = (ConfMan.getInt("music_volume") + 1)  * 100 / Audio::Mixer::kMaxMixerVolume;
 		const int16 sfxVolume    = (ConfMan.getInt("sfx_volume") + 1)    * 100 / Audio::Mixer::kMaxMixerVolume;
@@ -960,6 +969,7 @@ void GuestAdditions::syncAudioVolumeGlobalsToScummVM(const int index, const reg_
 		}
 		break;
 
+	case GID_LSL7:
 	case GID_TORIN:
 		if (index == kGlobalVarTorinMusicVolume ||
 			index == kGlobalVarTorinSFXVolume ||
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 8c000dd..6dcdaac 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -262,6 +262,22 @@ static const uint16 sci2BenchmarkPatch[] = {
 	PATCH_END
 };
 
+// Torin/LSL7-specific version of sci2NumSavesSignature1/2
+// Applies to at least: English CD
+static const uint16 torinNumSavesSignature[] = {
+	SIG_MAGICDWORD,
+	0x36,       // push
+	0x35, 0x14, // ldi 20
+	0x20,       // ge?
+	SIG_END
+};
+
+static const uint16 torinNumSavesPatch[] = {
+	PATCH_ADDTOOFFSET(+1), // push
+	0x35, 0x63,            // ldi 99
+	PATCH_END
+};
+
 #endif
 
 // ===========================================================================
@@ -2565,6 +2581,61 @@ static const SciScriptPatcherEntry larry6HiresSignatures[] = {
 #pragma mark -
 #pragma mark Leisure Suit Larry 7
 
+// The init code that runs when LSL7 starts up unconditionally resets the audio
+// volumes to defaults, but the game should always use the volume stored in
+// ScummVM. This patch is basically identical to the patch for Torin, except
+// that they left line numbers in the LSL7 scripts and changed the music volume.
+// Applies to at least: English CD
+static const uint16 larry7VolumeResetSignature1[] = {
+	SIG_MAGICDWORD,
+	0x35, 0x41,               // ldi $41
+	0xa1, 0xe3,               // sag $e3 (music volume)
+	0x7e, SIG_ADDTOOFFSET(2), // line whatever
+	0x35, 0x3c,               // ldi $3c
+	0xa1, 0xe4,               // sag $e4 (sfx volume)
+	0x7e, SIG_ADDTOOFFSET(2), // line whatever
+	0x35, 0x64,               // ldi $64
+	0xa1, 0xe5,               // sag $e5 (speech volume)
+	SIG_END
+};
+
+static const uint16 larry7VolumeResetPatch1[] = {
+	0x33, 0x10, // jmp [past volume resets]
+	PATCH_END
+};
+
+// The init code that runs when LSL7 starts up unconditionally resets the
+// audio volumes to values stored in larry7.prf, but the game should always use
+// the volume stored in ScummVM. This patch is basically identical to the patch
+// for Torin, except that they left line numbers in the LSL7 scripts.
+// Applies to at least: English CD
+static const uint16 larry7VolumeResetSignature2[] = {
+	SIG_MAGICDWORD,
+	0x38, SIG_UINT16(0x19d), // pushi readWord
+	0x76,                    // push0
+	SIG_ADDTOOFFSET(6),      // advance file stream
+	0xa1, 0xe3,              // sag $e3 (music volume)
+	SIG_ADDTOOFFSET(3),      // line whatever
+	SIG_ADDTOOFFSET(10),     // advance file stream
+	0xa1, 0xe4,              // sag $e4 (sfx volume)
+	SIG_ADDTOOFFSET(3),      // line whatever
+	SIG_ADDTOOFFSET(10),     // advance file stream
+	0xa1, 0xe5,              // sag $e5 (speech volume)
+	SIG_END
+};
+
+static const uint16 larry7VolumeResetPatch2[] = {
+	PATCH_ADDTOOFFSET(10), // advance file stream
+	0x18, 0x18,            // waste bytes
+	PATCH_ADDTOOFFSET(3),  // line whatever
+	PATCH_ADDTOOFFSET(10), // advance file stream
+	0x18, 0x18,            // waste bytes
+	PATCH_ADDTOOFFSET(3),  // line whatever
+	PATCH_ADDTOOFFSET(10), // advance file stream
+	0x18, 0x18,            // waste bytes
+	PATCH_END
+};
+
 // ===========================================================================
 // In room 540 of Leisure Suit Larry 7, Larry will use 4 items on a so called cheese maker.
 //  A short cutscene will then play.
@@ -2628,10 +2699,33 @@ static const uint16 larry7PatchMakeCheesePriority[] = {
 	PATCH_END
 };
 
+// LSL7 tries to reset the message type twice at startup, first with a default
+// value in script 0, then with a stored value from larry7.prf (if that file
+// exists) or the same default value (if it does not) in script 64000. Since
+// message type sync relies on the game only setting this value once at startup,
+// we must stop the second attempt or the value from ScummVM will be
+// overwritten.
+// Applies to at least: English CD
+static const uint16 larry7MessageTypeResetSignature[] = {
+	SIG_MAGICDWORD,
+	0x35, 0x02, // ldi 2
+	0xa1, 0x5a, // sag $5a
+	SIG_END
+};
+
+static const uint16 larry7MessageTypeResetPatch[] = {
+	0x33, 0x02, // jmp [past reset]
+	PATCH_END
+};
+
 //          script, description,                                signature                           patch
 static const SciScriptPatcherEntry larry7Signatures[] = {
+	{  true,     0, "disable message type reset on startup", 1, larry7MessageTypeResetSignature,    larry7MessageTypeResetPatch },
 	{  true,   540, "fix make cheese cutscene (cycler)",     1, larry7SignatureMakeCheese,          larry7PatchMakeCheese },
 	{  true,   540, "fix make cheese cutscene (priority)",   1, larry7SignatureMakeCheesePriority,  larry7PatchMakeCheesePriority },
+	{  true, 64000, "disable volume reset on startup 1/2",   1, larry7VolumeResetSignature1,        larry7VolumeResetPatch1 },
+	{  true, 64000, "disable volume reset on startup 2/2",   1, larry7VolumeResetSignature2,        larry7VolumeResetPatch2 },
+	{  true, 64866, "increase number of save games",         1, torinNumSavesSignature,             torinNumSavesPatch },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -5652,8 +5746,9 @@ static const SciScriptPatcherEntry sq6Signatures[] = {
 #pragma mark Torins Passage
 
 // The init code that runs when Torin starts up unconditionally resets the
-// master music volume to defaults, but the game should always use the volume
-// stored in ScummVM.
+// audio volumes to defaults, but the game should always use the volume stored
+// in ScummVM. This patch is basically identical to the patch for LSL7, except
+// that they left line numbers in the LSL7 scripts and changed the music volume.
 // Applies to at least: English CD
 static const uint16 torinVolumeResetSignature1[] = {
 	SIG_MAGICDWORD,
@@ -5672,8 +5767,9 @@ static const uint16 torinVolumeResetPatch1[] = {
 };
 
 // The init code that runs when Torin starts up unconditionally resets the
-// master music volume to values stored in torin.prf, but the game should always
-// use the volume stored in ScummVM.
+// audio volumes to values stored in torin.prf, but the game should always use
+// the volume stored in ScummVM. This patch is basically identical to the patch
+// for LSL7, except that they left line numbers in the LSL7 scripts.
 // Applies to at least: English CD
 static const uint16 torinVolumeResetSignature2[] = {
 	SIG_MAGICDWORD,
@@ -5698,22 +5794,6 @@ static const uint16 torinVolumeResetPatch2[] = {
 	PATCH_END
 };
 
-// Torin-specific version of sci2NumSavesSignature1/2
-// Applies to at least: English CD
-static const uint16 torinNumSavesSignature[] = {
-	SIG_MAGICDWORD,
-	0x36,       // push
-	0x35, 0x14, // ldi 20
-	0x20,       // ge?
-	SIG_END
-};
-
-static const uint16 torinNumSavesPatch[] = {
-	PATCH_ADDTOOFFSET(+1), // push
-	0x35, 0x63,            // ldi 99
-	PATCH_END
-};
-
 // In Escarpa, it is possible for Boogle to be left outside of Torin's bag
 // when fast-forwarding through the exit animation of the seraglio. If this
 // happens, when the player goes from the seraglio to the dragon's cave and then
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index e28ae79..9c6921b 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -217,6 +217,7 @@ void Kernel::mapSelectors() {
 	FIND_SELECTOR(setPos);
 	FIND_SELECTOR(setSize);
 	FIND_SELECTOR(displayValue);
+	FIND_SELECTOR2(new_, "new");
 #endif
 }
 
diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h
index 1db9e4b..d97a883 100644
--- a/engines/sci/engine/selector.h
+++ b/engines/sci/engine/selector.h
@@ -174,6 +174,7 @@ struct SelectorCache {
 	Selector setPos; // for Torin volume sync
 	Selector setSize; // for PQ4 volume sync
 	Selector displayValue; // for PQ:SWAT volume sync
+	Selector new_; // for Torin/LSL7 save/load patching
 #endif
 };
 


Commit: 09ef11a8cbd86375458d0ea8efd3a2e770dd3b89
    https://github.com/scummvm/scummvm/commit/09ef11a8cbd86375458d0ea8efd3a2e770dd3b89
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-07-17T22:42:18-05:00

Commit Message:
SCI32: Remove ENABLE_SCI3_GAMES ifdef, now that they are supported

Changed paths:
    engines/sci/detection_tables.h
    engines/sci/graphics/palette32.cpp


diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index ab504cb..5a5c878 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -24,9 +24,6 @@ namespace Sci {
 
 #include "sci/sci.h"
 
-// SCI3 games have a different script format (in CSC files) and are currently unsupported
-#define ENABLE_SCI3_GAMES
-
 #define FANMADE_L(name, resMapMd5, resMapSize, resMd5, resSize, lang) \
 	{"sci-fanmade", name, { \
 		{"resource.map", 0, resMapMd5, resMapSize}, \
@@ -2710,7 +2707,6 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO_LSL7_DEMO },
 
-#ifdef ENABLE_SCI3_GAMES
 	// Larry 7 - English DOS CD (from spookypeanut)
 	// SCI interpreter version 3.000.000
 	{"lsl7", "", {
@@ -2754,8 +2750,6 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 #undef GUIO_LSL7_DEMO
 #undef GUIO_LSL7
 
-#endif
-
 // TODO: Correct GUIOs
 #define GUIO_LIGHTHOUSE_DEMO GUIO3(GUIO_NOSPEECH, \
                                    GUIO_NOASPECT, \
@@ -2773,7 +2767,6 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO_LIGHTHOUSE_DEMO },
 
-#ifdef ENABLE_SCI3_GAMES
 	// Lighthouse - English Windows Demo
 	// Executable scanning reports "3.000.000", VERSION file reports "1.00"
 	{"lighthouse", "Demo", {
@@ -2825,8 +2818,6 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 #undef GUIO_LIGHTHOUSE_DEMO
 #undef GUIO_LIGHTHOUSE
 
-#endif	// ENABLE_SCI3_GAMES
-
 #endif // ENABLE_SCI32
 
 	// Mixed-Up Fairy Tales v1.000 - English DOS Non-Interactive Demo
@@ -3133,8 +3124,6 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 #undef GUIO_PHANTASMAGORIA
 #undef GUIO_PHANTASMAGORIA_MAC
 
-#ifdef ENABLE_SCI3_GAMES
-
 // TODO: Correct GUIOs
 #define GUIO_PHANTASMAGORIA2 GUIO5(GUIO_NOASPECT, \
                                    GUIO_NOMIDI, \
@@ -3238,7 +3227,6 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		//{"ressfx.001", 0, "343a6ca9ddd614541b11b155de6368ac", 90268706},
 		AD_LISTEND},
 		Common::JA_JPN, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_PHANTASMAGORIA2 },
-#endif	// ENABLE_SCI3_GAMES
 
 #endif // ENABLE_SCI32
 
@@ -4002,7 +3990,6 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_RAMA_DEMO },
 
-#ifdef ENABLE_SCI3_GAMES
 	// RAMA - English Windows (from jvprat)
 	// Executable scanning reports "3.000.000", VERSION file reports "1.100.000"
 	{"rama", "", {
@@ -4060,8 +4047,6 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 #undef GUIO_RAMA_DEMO
 #undef GUIO_RAMA
 
-#endif	// ENABLE_SCI3_GAMES
-
 #define GUIO_SHIVERS_DEMO GUIO6(GUIO_NOSUBTITLES, \
                                 GUIO_NOMIDI, \
                                 GUIO_NOLAUNCHLOAD, \
diff --git a/engines/sci/graphics/palette32.cpp b/engines/sci/graphics/palette32.cpp
index 0ea64d6..4b008dd 100644
--- a/engines/sci/graphics/palette32.cpp
+++ b/engines/sci/graphics/palette32.cpp
@@ -391,9 +391,6 @@ static const uint8 gammaTables[GfxPalette32::numGammaTables][256] = {
 }
 
 GfxPalette32::~GfxPalette32() {
-#ifdef ENABLE_SCI3_GAMES
-	unloadClut();
-#endif
 	varyOff();
 	cycleAllOff();
 }


Commit: ba4fccdb26ff050fad32d24956e9eba7e8fa6268
    https://github.com/scummvm/scummvm/commit/ba4fccdb26ff050fad32d24956e9eba7e8fa6268
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-07-17T23:56:21-05:00

Commit Message:
SCI32: Add workaround for Torin/LSL7 running with subtitles only

Since these later SCI32 games weren't really designed to work with
subtitles-only message mode, if this doesn't work consistently or
breaks the games a lot in other places, the subtitles-only message
type could possibly be implemented in some other way, like by
messing with the game's speech volume global instead.

Changed paths:
    engines/sci/engine/workarounds.cpp


diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index a43df75..9eab4b3 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -348,6 +348,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
 	{ GID_LSL6HIRES,      -1,    85,  0,          "washcloth", "doVerb",                          NULL,     0, { WORKAROUND_FAKE,   0 } }, // when interacting with the wet washcloth in the inventory - Trac#9811
 	{ GID_LSL6HIRES,      -1, 64950,  1,            "Feature", "handleEvent",                     NULL,     0, { WORKAROUND_FAKE,   0 } }, // at least when entering swimming pool area
 	{ GID_LSL6HIRES,      -1, 64964,  0,              "DPath", "init",                            NULL,     1, { WORKAROUND_FAKE,   0 } }, // during the game
+	{ GID_LSL7,           -1, 64029,  0,          "oMessager", "nextMsg",                         NULL,     4, { WORKAROUND_FAKE,   0 } }, // when running the game with subtitles only
 	{ GID_LSL7,           -1, 64017,  0,             "oFlags", "clear",                           NULL,     0, { WORKAROUND_FAKE,   0 } }, // demo version, when it starts, and whenever the player chooses to go to the "Strip Liar's Dice" mini game
 	{ GID_LSL7,           -1, 64017,  0,        "oActorFlags", "clear",                           NULL,     0, { WORKAROUND_FAKE,   0 } }, // after an NPC walks off the left side of the screen at the Clothing Optional Pool
 	{ GID_LSL7,           -1, 64892,  0,      "oEventHandler", "killAllEventHogs",                NULL,     1, { WORKAROUND_FAKE,   0 } }, // when looking at the swordfish in the kitchen
@@ -423,7 +424,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
 	{ GID_SQ6,            -1, 64994, -1,               "Game", "restore",                         NULL,     1, { WORKAROUND_FAKE,   0 } }, // When trying to load an invalid save game from the launcher
 	{ GID_SQ6,            -1, 64921, -1,              "Print", "addEdit",                         NULL,     1, { WORKAROUND_FAKE,   0 } }, // When trying to use the game debugger's flag setting command
 	{ GID_TORIN,          -1, 64017,  0,             "oFlags", "clear",                           NULL,     0, { WORKAROUND_FAKE,   0 } }, // entering Torin's home in the French version
-	{ GID_TORIN,       10000, 64029,  0,          "oMessager", "nextMsg",                         NULL,     3, { WORKAROUND_FAKE,   0 } }, // start of chapter one
+	{ GID_TORIN,          -1, 64029,  0,          "oMessager", "nextMsg",                         NULL,     3, { WORKAROUND_FAKE,   0 } }, // start of chapter one, or when running with subtitles only
 	{ GID_TORIN,          -1, 64892,  0,      "oEventHandler", "killAllEventHogs",                NULL,     1, { WORKAROUND_FAKE,   0 } }, // when pressing the hint button when the game is about to transition to a new room (race condition) - Trac#9810
 	{ GID_TORIN,       20100, 64964,  0,              "DPath", "init",                            NULL,     1, { WORKAROUND_FAKE,   0 } }, // going down the cliff at the first screen of chapter 2 (washing area)
 	{ GID_TORIN,       61100, 64888,  0,              "Torin", "autorestore",                     NULL,    11, { WORKAROUND_FAKE,   0 } }, // after attempting to restore a save game saved with the wrong game version


Commit: 64d090dcb82377daa09587f92b7c00c8f96b3a0c
    https://github.com/scummvm/scummvm/commit/64d090dcb82377daa09587f92b7c00c8f96b3a0c
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-07-17T23:56:21-05:00

Commit Message:
SCI32: Fix stream leaks in Audio32/SOLStream

makeSOLStream was leaking the SeekableSubReadStream object it
creates itself if it was not called with DisposeAfterUse::YES. That
substream is an implementation detail which should not rely on
the caller to be destroyed.

Changed paths:
    engines/sci/sound/decoders/sol.cpp


diff --git a/engines/sci/sound/decoders/sol.cpp b/engines/sci/sound/decoders/sol.cpp
index d060fae..50d353c 100644
--- a/engines/sci/sound/decoders/sol.cpp
+++ b/engines/sci/sound/decoders/sol.cpp
@@ -254,20 +254,20 @@ Audio::SeekableAudioStream *makeSOLStream(Common::SeekableReadStream *stream, Di
 
 	if (flags & kCompressed) {
 		if (flags & kStereo && flags & k16Bit) {
-			return new SOLStream<true, true, false>(new Common::SeekableSubReadStream(stream, initialPosition, initialPosition + dataSize, disposeAfterUse), disposeAfterUse, sampleRate, dataSize);
+			return new SOLStream<true, true, false>(new Common::SeekableSubReadStream(stream, initialPosition, initialPosition + dataSize, disposeAfterUse), DisposeAfterUse::YES, sampleRate, dataSize);
 		} else if (flags & kStereo) {
 			if (getSciVersion() < SCI_VERSION_2_1_EARLY) {
 				error("SCI2 and earlier did not support stereo SOL audio");
 			}
 
-			return new SOLStream<true, false, false>(new Common::SeekableSubReadStream(stream, initialPosition, initialPosition + dataSize, disposeAfterUse), disposeAfterUse, sampleRate, dataSize);
+			return new SOLStream<true, false, false>(new Common::SeekableSubReadStream(stream, initialPosition, initialPosition + dataSize, disposeAfterUse), DisposeAfterUse::YES, sampleRate, dataSize);
 		} else if (flags & k16Bit) {
-			return new SOLStream<false, true, false>(new Common::SeekableSubReadStream(stream, initialPosition, initialPosition + dataSize, disposeAfterUse), disposeAfterUse, sampleRate, dataSize);
+			return new SOLStream<false, true, false>(new Common::SeekableSubReadStream(stream, initialPosition, initialPosition + dataSize, disposeAfterUse), DisposeAfterUse::YES, sampleRate, dataSize);
 		} else {
 			if (getSciVersion() < SCI_VERSION_2_1_EARLY) {
-				return new SOLStream<false, false, true>(new Common::SeekableSubReadStream(stream, initialPosition, initialPosition + dataSize, disposeAfterUse), disposeAfterUse, sampleRate, dataSize);
+				return new SOLStream<false, false, true>(new Common::SeekableSubReadStream(stream, initialPosition, initialPosition + dataSize, disposeAfterUse), DisposeAfterUse::YES, sampleRate, dataSize);
 			} else {
-				return new SOLStream<false, false, false>(new Common::SeekableSubReadStream(stream, initialPosition, initialPosition + dataSize, disposeAfterUse), disposeAfterUse, sampleRate, dataSize);
+				return new SOLStream<false, false, false>(new Common::SeekableSubReadStream(stream, initialPosition, initialPosition + dataSize, disposeAfterUse), DisposeAfterUse::YES, sampleRate, dataSize);
 			}
 		}
 	}


Commit: dcb6c3221523b19857d0f5fcbb7409140a80e903
    https://github.com/scummvm/scummvm/commit/dcb6c3221523b19857d0f5fcbb7409140a80e903
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-07-17T23:56:21-05:00

Commit Message:
SCI32: Destroy audio streams in Audio32 using DisposeAfterUse flag

Since Resource::makeStream returns a MemoryReadStream which will
not attempt to free the resource memory, it is fine to always
dispose those streams and get rid of the separate resourceStream
property, which was a holdover from some past WIP resource design
which no longer exists.

Changed paths:
    engines/sci/sound/audio32.cpp
    engines/sci/sound/audio32.h


diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp
index 0bef60b..04d1a47 100644
--- a/engines/sci/sound/audio32.cpp
+++ b/engines/sci/sound/audio32.cpp
@@ -557,8 +557,6 @@ void Audio32::freeChannel(const int16 channelIndex) {
 		channel.resource = nullptr;
 		delete channel.stream;
 		channel.stream = nullptr;
-		delete channel.resourceStream;
-		channel.resourceStream = nullptr;
 	}
 
 	delete channel.converter;
@@ -797,14 +795,14 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 		_monitoredChannelIndex = channelIndex;
 	}
 
-	Common::SeekableReadStream *dataStream = channel.resourceStream = resource->makeStream();
+	Common::SeekableReadStream *dataStream = resource->makeStream();
 
 	Audio::RewindableAudioStream *audioStream;
 
 	if (detectSolAudio(*dataStream)) {
-		audioStream = makeSOLStream(dataStream, DisposeAfterUse::NO);
+		audioStream = makeSOLStream(dataStream, DisposeAfterUse::YES);
 	} else if (detectWaveAudio(*dataStream)) {
-		audioStream = Audio::makeWAVStream(dataStream, DisposeAfterUse::NO);
+		audioStream = Audio::makeWAVStream(dataStream, DisposeAfterUse::YES);
 	} else {
 		byte flags = Audio::FLAG_LITTLE_ENDIAN;
 		if (_globalBitDepth == 16) {
@@ -817,7 +815,7 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 			flags |= Audio::FLAG_STEREO;
 		}
 
-		audioStream = Audio::makeRawStream(dataStream, _globalSampleRate, flags, DisposeAfterUse::NO);
+		audioStream = Audio::makeRawStream(dataStream, _globalSampleRate, flags, DisposeAfterUse::YES);
 	}
 
 	channel.stream = new MutableLoopAudioStream(audioStream, loop);
diff --git a/engines/sci/sound/audio32.h b/engines/sci/sound/audio32.h
index 59f96a8..a994113e 100644
--- a/engines/sci/sound/audio32.h
+++ b/engines/sci/sound/audio32.h
@@ -52,11 +52,6 @@ struct AudioChannel {
 	Resource *resource;
 
 	/**
-	 * Data stream containing the raw audio for the channel.
-	 */
-	Common::SeekableReadStream *resourceStream;
-
-	/**
 	 * The audio stream loaded into this channel. Can cast
 	 * to `SeekableAudioStream` for normal channels and
 	 * `RobotAudioStream` for robot channels.


Commit: 9d62caa684feb2e403783a0b8f1fd11a1457436d
    https://github.com/scummvm/scummvm/commit/9d62caa684feb2e403783a0b8f1fd11a1457436d
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-07-17T23:56:22-05:00

Commit Message:
SCI32: Promote LSL7 to ADGF_TESTING

Changed paths:
    engines/sci/detection_tables.h


diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 5a5c878..4d8290d 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -2705,7 +2705,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878},
 		{"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695},
 		AD_LISTEND},
-		Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO_LSL7_DEMO },
+		Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_TESTING, GUIO_LSL7_DEMO },
 
 	// Larry 7 - English DOS CD (from spookypeanut)
 	// SCI interpreter version 3.000.000
@@ -2713,7 +2713,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"resmap.000", 0, "eae93e1b1d1ccc58b4691c371281c95d", 8188},
 		{"ressci.000", 0, "89353723488219e25589165d73ed663e", 66965678},
 		AD_LISTEND},
-		Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO_LSL7 },
+		Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_TESTING, GUIO_LSL7 },
 
 	// Larry 7 - German DOS (from Tobis87)
 	// SCI interpreter version 3.000.000
@@ -2721,7 +2721,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"resmap.000", 0, "c11e6bfcfc2f2d05da47e5a7df3e9b1a", 8188},
 		{"ressci.000", 0, "a8c6817bb94f332ff498a71c8b47f893", 66971724},
 		AD_LISTEND},
-		Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO_LSL7 },
+		Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_TESTING, GUIO_LSL7 },
 
 	// Larry 7 - French DOS (provided by richiefs in bug report #2670691)
 	// SCI interpreter version 3.000.000
@@ -2729,7 +2729,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"resmap.000", 0, "4407849fd52fe3efb0c30fba60cd5cd4", 8206},
 		{"ressci.000", 0, "dc37c3055fffbefb494ff22b145d377b", 66964472},
 		AD_LISTEND},
-		Common::FR_FRA, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO_LSL7 },
+		Common::FR_FRA, Common::kPlatformDOS, ADGF_CD | ADGF_TESTING, GUIO_LSL7 },
 
 	// Larry 7 - Italian DOS CD (from glorifindel)
 	// SCI interpreter version 3.000.000
@@ -2737,7 +2737,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"resmap.000", 0, "9852a97141f789413f29bf956052acdb", 8212},
 		{"ressci.000", 0, "440b9fed89590abb4e4386ed6f948ee2", 67140181},
 		AD_LISTEND},
-		Common::IT_ITA, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO_LSL7 },
+		Common::IT_ITA, Common::kPlatformDOS, ADGF_CD | ADGF_TESTING, GUIO_LSL7 },
 
 	// Larry 7 - Spanish DOS (from the Leisure Suit Larry Collection)
 	// Executable scanning reports "3.000.000", VERSION file reports "1.0s"
@@ -2745,7 +2745,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"resmap.000", 0, "8f3d603e1acc834a5d598b30cdfc93f3", 8188},
 		{"ressci.000", 0, "32792f9bc1bf3633a88b382bb3f6e40d", 67071418},
 		AD_LISTEND},
-		Common::ES_ESP, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO_LSL7 },
+		Common::ES_ESP, Common::kPlatformDOS, ADGF_CD | ADGF_TESTING, GUIO_LSL7 },
 
 #undef GUIO_LSL7_DEMO
 #undef GUIO_LSL7





More information about the Scummvm-git-logs mailing list