[Scummvm-git-logs] scummvm master -> 10db6e9a44db071e75fd7e7882ebdd90e786af98

csnover csnover at users.noreply.github.com
Sun Sep 10 06:38:07 CEST 2017


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

Summary:
e137d01967 SCI32: Fix Phant2 movie-vs-game playback volumes
f200cc110f SCI32: Send correct color depth to Phant2
393c0d1f62 SCI32: Fix whitespace errors
41506201b9 AUDIO: Fix incorrect reading of DK3 ADPCM audio data
10db6e9a44 AUDIO: Mark SCI engine as using ADPCM


Commit: e137d01967021d8fceef45c727615c797a9cdd91
    https://github.com/scummvm/scummvm/commit/e137d01967021d8fceef45c727615c797a9cdd91
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-09-09T23:29:57-05:00

Commit Message:
SCI32: Fix Phant2 movie-vs-game playback volumes

This update should give the game the default mix it receives in
Windows. If necessary, the half-volume audio bug in the DOS
interpreter can be added as an additional hack for this game, since
there are still some sub-par audio mixes that might need additional
correction (like Curtis talking to Blob when taking her out of the
cage in his apartment at the start of the game) which were also
bad in the Windows version of the game.

Fixes Trac#10165.

Changed paths:
    engines/sci/engine/guest_additions.cpp
    engines/sci/engine/guest_additions.h
    engines/sci/engine/script_patches.cpp
    engines/sci/engine/vm.h
    engines/sci/sound/audio32.cpp


diff --git a/engines/sci/engine/guest_additions.cpp b/engines/sci/engine/guest_additions.cpp
index 0452cc2..90d797a 100644
--- a/engines/sci/engine/guest_additions.cpp
+++ b/engines/sci/engine/guest_additions.cpp
@@ -50,12 +50,6 @@ enum {
 	kMessageTypeSpeech    = 2
 };
 
-enum {
-	kLSL6HiresUIVolumeMax  = 13,
-	kLSL6HiresSubtitleFlag = 105
-};
-
-
 GuestAdditions::GuestAdditions(EngineState *state, GameFeatures *features, Kernel *kernel) :
 	_state(state),
 	_features(features),
@@ -912,7 +906,7 @@ void GuestAdditions::syncAudioVolumeGlobalsFromScummVM() const {
 	}
 
 	case GID_PHANTASMAGORIA2: {
-		const int16 masterVolume = (ConfMan.getInt("sfx_volume") + 1) * Audio32::kMaxVolume / Audio::Mixer::kMaxMixerVolume;
+		const int16 masterVolume = (ConfMan.getInt("sfx_volume") + 1) * kPhant2VolumeMax / Audio::Mixer::kMaxMixerVolume;
 		syncPhant2VolumeFromScummVM(masterVolume);
 		syncPhant2UI(masterVolume);
 		break;
@@ -1016,12 +1010,13 @@ void GuestAdditions::syncLSL6HiresVolumeFromScummVM(const int16 musicVolume) con
 	g_sci->_soundCmd->setMasterVolume(ConfMan.getBool("mute") ? 0 : (musicVolume * MUSIC_MASTERVOLUME_MAX / kLSL6HiresUIVolumeMax));
 }
 
-void GuestAdditions::syncPhant2VolumeFromScummVM(const int16 musicVolume) const {
-	_state->variables[VAR_GLOBAL][kGlobalVarPhant2MasterVolume] = make_reg(0, musicVolume);
+void GuestAdditions::syncPhant2VolumeFromScummVM(const int16 masterVolume) const {
+	_state->variables[VAR_GLOBAL][kGlobalVarPhant2MasterVolume] = make_reg(0, masterVolume);
+	_state->variables[VAR_GLOBAL][kGlobalVarPhant2SecondaryVolume] = make_reg(0, masterVolume);
 
 	const reg_t soundsId = _state->variables[VAR_GLOBAL][kGlobalVarSounds];
 	if (!soundsId.isNull()) {
-		reg_t params[] = { make_reg(0, SELECTOR(setVol)), make_reg(0, musicVolume) };
+		reg_t params[] = { make_reg(0, SELECTOR(setVol)), make_reg(0, masterVolume) };
 		invokeSelector(soundsId, SELECTOR(eachElementDo), 2, params);
 	}
 }
@@ -1080,7 +1075,7 @@ void GuestAdditions::syncAudioVolumeGlobalsToScummVM(const int index, const reg_
 
 	case GID_PHANTASMAGORIA2:
 		if (index == kGlobalVarPhant2MasterVolume) {
-			const int16 masterVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / Audio32::kMaxVolume;
+			const int16 masterVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / kPhant2VolumeMax;
 			ConfMan.setInt("music_volume", masterVolume);
 			ConfMan.setInt("sfx_volume", masterVolume);
 			ConfMan.setInt("speech_volume", masterVolume);
@@ -1247,18 +1242,18 @@ void GuestAdditions::syncPhant1UI(const int16 oldMusicVolume, const int16 musicV
 	}
 }
 
-void GuestAdditions::syncPhant2UI(const int16 musicVolume) const {
-	const reg_t musicVolumeScript = _segMan->findObjectByName("foo2");
+void GuestAdditions::syncPhant2UI(const int16 masterVolume) const {
+	const reg_t masterVolumeScript = _segMan->findObjectByName("foo2");
 	Common::Array<reg_t> scrollBars = _segMan->findObjectsByName("P2ScrollBar");
 	for (uint i = 0; i < scrollBars.size(); ++i) {
-		if (readSelector(_segMan, scrollBars[i], SELECTOR(client)) == musicVolumeScript) {
+		if (readSelector(_segMan, scrollBars[i], SELECTOR(client)) == masterVolumeScript) {
 			// P2ScrollBar objects may exist without actually being on-screen;
 			// the easiest way to tell seems to be to look to see if it has
 			// non-null pointers to subviews. (The game will correctly set the
 			// position of the scrollbar when it first becomes visible, so this
 			// is fine.)
 			if (!readSelector(_segMan, scrollBars[i], SELECTOR(physicalBar)).isNull()) {
-				reg_t params[] = { make_reg(0, musicVolume), make_reg(0, 1) };
+				reg_t params[] = { make_reg(0, masterVolume), make_reg(0, 1) };
 				invokeSelector(scrollBars[i], SELECTOR(move), 2, params);
 				break;
 			}
diff --git a/engines/sci/engine/guest_additions.h b/engines/sci/engine/guest_additions.h
index 7c80c29..64bd667 100644
--- a/engines/sci/engine/guest_additions.h
+++ b/engines/sci/engine/guest_additions.h
@@ -33,6 +33,21 @@ class Kernel;
 class Script;
 class SegManager;
 
+#ifdef ENABLE_SCI32
+enum {
+	// The in-game volumes for Phant2 use a volume range smaller than the
+	// actual master volume because movie volume needs to be controllable from
+	// the normal ScummVM launcher volume controls, but movie dialogue cannot be
+	// heard if the game audio is at the same level as movies. The game normally
+	// sets defaults so that the in-game volume is 85 and movies are 127, so we
+	// will just use 85 as the maximum volume.
+	kPhant2VolumeMax       = 85,
+
+	kLSL6HiresUIVolumeMax  = 13,
+	kLSL6HiresSubtitleFlag = 105
+};
+#endif
+
 /**
  * The GuestAdditions class hooks into the SCI virtual machine to provide
  * enhanced interactions between the ScummVM GUI and the game engine. Currently,
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 4439201..e845848 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -26,6 +26,9 @@
 #include "sci/engine/state.h"
 #include "sci/engine/features.h"
 #include "sci/engine/script_patches.h"
+#ifdef ENABLE_SCI32
+#include "sci/engine/guest_additions.h"
+#endif
 
 #include "common/util.h"
 
@@ -3879,6 +3882,29 @@ static const uint16 phant2RatboyPatch[] = {
 	PATCH_END
 };
 
+// Phant2 has separate in-game volume controls for handling movie volume and
+// in-game volume (misleading labelled "music volume"), but really needs the
+// in-game volume to always be significantly lower than the movie volume in
+// order for dialogue in movies to be consistently audible, so patch the in-game
+// volume slider to limit it to our maximum.
+// Applies to at least: US English
+static const uint16 phant2AudioVolumeSignature[] = {
+	SIG_MAGICDWORD,
+	0x39, 0x7f,           // pushi 127 (clientMax)
+	0x39, 0x14,           // pushi 20  (clientPageSize)
+	SIG_ADDTOOFFSET(+10), // skip other init arguments
+	0x51, 0x5e,           // class P2ScrollBar
+	SIG_ADDTOOFFSET(+3),  // skip send
+	0xa3, 0x06,           // sal 6 (identifies correct slider)
+	SIG_END
+};
+
+static const uint16 phant2AudioVolumePatch[] = {
+	0x39, kPhant2VolumeMax,              // pushi (our custom volume max)
+	0x39, 0x14 * kPhant2VolumeMax / 127, // pushi (ratio of original value)
+	PATCH_END
+};
+
 // When censorship is disabled the game sticks <PROTECTED> at the end of every
 // save game name, and when it is enabled it pads the save game name with a
 // bunch of spaces. This is annoying and not helpful, so just disable all of
@@ -3945,6 +3971,7 @@ static const SciScriptPatcherEntry phantasmagoria2Signatures[] = {
 	{  true,     0, "slow interface fades",                        3, phant2SlowIFadeSignature,      phant2SlowIFadePatch },
 	{  true,     0, "bad arguments to get game version",           1, phant2GetVersionSignature,     phant2GetVersionPatch },
 	{  true,  4081, "non-responsive mouse after ratboy puzzle",    1, phant2RatboySignature,         phant2RatboyPatch },
+	{  true, 63004, "limit in-game audio volume",                  1, phant2AudioVolumeSignature,    phant2AudioVolumePatch },
 	{  true, 63016, "non-responsive mouse during music fades",     1, phant2Wait4FadeSignature,      phant2Wait4FadePatch },
 	{  true, 63019, "non-responsive mouse during computer load",   1, phant2CompSlideDoorsSignature, phant2CompSlideDoorsPatch },
 	{  true, 64990, "remove save game name mangling (1/2)",        1, phant2SaveNameSignature1,      phant2SaveNamePatch1 },
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index 67729bf..792287b 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -149,9 +149,10 @@ enum GlobalVar {
 	kGlobalVarNewRoomNo      = 13,
 	kGlobalVarScore          = 15,
 	kGlobalVarGK2MusicVolume = 76, // 0 to 127
-	kGlobalVarFastCast       = 84, // SCI16
-	kGlobalVarMessageType    = 90,
-	kGlobalVarTextSpeed      = 94, // SCI32; 0 is fastest, 8 is slowest
+	kGlobalVarPhant2SecondaryVolume = 76, // 0 to 127
+	kGlobalVarFastCast             = 84, // SCI16
+	kGlobalVarMessageType          = 90,
+	kGlobalVarTextSpeed            = 94, // SCI32; 0 is fastest, 8 is slowest
 	kGlobalVarGK1Music1            = 102, // 0 to 127
 	kGlobalVarGK1Music2            = 103, // 0 to 127
 	kGlobalVarLSL6HiresGameFlags   = 137,
diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp
index c3f9eb4..ad9af4e 100644
--- a/engines/sci/sound/audio32.cpp
+++ b/engines/sci/sound/audio32.cpp
@@ -359,6 +359,17 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
 				} else if (volume > 84 && volume < kMaxVolume) {
 					volume = 63;
 				}
+			} else if (getSciVersion() == SCI_VERSION_3 && volume != kMaxVolume) {
+				// In SCI3, granularity of the non-maximum volumes is 1/32
+				volume &= ~4;
+
+				// NOTE: In the SSCI DOS interpreter, non-maximum volumes are
+				// divided by 8 which puts them in a range of [0, 16). That
+				// reduced volume range gets passed into a volume function which
+				// expects values [0, 32). So, effectively, all non-maximum
+				// volumes are half-volume in DOS in SCI3. In Windows, volumes
+				// [120, 124) are the same as 127 due to a programming bug.
+				// We do not emulate either of these incorrect behaviors.
 			}
 
 			leftVolume = rightVolume = volume * Audio::Mixer::kMaxChannelVolume / kMaxVolume;


Commit: f200cc110fbdecb9472cc1503b6d011802f6986b
    https://github.com/scummvm/scummvm/commit/f200cc110fbdecb9472cc1503b6d011802f6986b
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-09-09T23:29:57-05:00

Commit Message:
SCI32: Send correct color depth to Phant2

This is not known to fix any particular issue, but the game does
set some flags internally if it's running in 256-color Windows,
which is possibly undesirable since we do run 16-bit videos
regardless.

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


diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index 6c5dcd1..af3b7bb 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -648,7 +648,11 @@ reg_t kPlatform32(EngineState *s, int argc, reg_t *argv) {
 			error("Unknown platform %d", g_sci->getPlatform());
 		}
 	case kGetColorDepth:
-		return make_reg(0, /* 256 color */ 2);
+		if (g_sci->getGameId() == GID_PHANTASMAGORIA2) {
+			return make_reg(0, /* 16-bit color */ 3);
+		} else {
+			return make_reg(0, /* 256 color */ 2);
+		}
 	case kGetCDSpeed:
 		// The value `4` comes from Rama DOS resource.cfg installed in DOSBox,
 		// and seems to correspond to the highest expected CD speed value


Commit: 393c0d1f6250d0fd13f201c7ae28e51bd8c93215
    https://github.com/scummvm/scummvm/commit/393c0d1f6250d0fd13f201c7ae28e51bd8c93215
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-09-09T23:29:57-05:00

Commit Message:
SCI32: Fix whitespace errors

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


diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index e845848..3eb697e 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -3966,7 +3966,7 @@ static const uint16 phant2NumSavesPatch2[] = {
 	PATCH_END
 };
 
-//          script, description,                                      signature                        patch
+//          script, description,                                      signature                      patch
 static const SciScriptPatcherEntry phantasmagoria2Signatures[] = {
 	{  true,     0, "slow interface fades",                        3, phant2SlowIFadeSignature,      phant2SlowIFadePatch },
 	{  true,     0, "bad arguments to get game version",           1, phant2GetVersionSignature,     phant2GetVersionPatch },
@@ -3976,8 +3976,8 @@ static const SciScriptPatcherEntry phantasmagoria2Signatures[] = {
 	{  true, 63019, "non-responsive mouse during computer load",   1, phant2CompSlideDoorsSignature, phant2CompSlideDoorsPatch },
 	{  true, 64990, "remove save game name mangling (1/2)",        1, phant2SaveNameSignature1,      phant2SaveNamePatch1 },
 	{  true, 64994, "remove save game name mangling (2/2)",        1, phant2SaveNameSignature2,      phant2SaveNamePatch2 },
-	{  true, 64990, "increase number of save games",               1, phant2NumSavesSignature1,       phant2NumSavesPatch1 },
-	{  true, 64990, "increase number of save games",               2, phant2NumSavesSignature2,       phant2NumSavesPatch2 },
+	{  true, 64990, "increase number of save games",               1, phant2NumSavesSignature1,      phant2NumSavesPatch1 },
+	{  true, 64990, "increase number of save games",               2, phant2NumSavesSignature2,      phant2NumSavesPatch2 },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 


Commit: 41506201b908347ae7fba88cfdd3bcc53e6b4056
    https://github.com/scummvm/scummvm/commit/41506201b908347ae7fba88cfdd3bcc53e6b4056
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-09-09T23:29:58-05:00

Commit Message:
AUDIO: Fix incorrect reading of DK3 ADPCM audio data

Previously, _topNibble was not reset at the beginning of a new
audio block, and the alignment byte at the end of odd blocks was
being read as audio data, which caused audible clicks and
out-of-bounds sample generation. There may have also been read
errors related to the use of continue/break keywords inside of a
macro wrapped with do-while(0).

The introduction of partial block reads in this code when it was
converted from ffmpeg to a ReadStream interface was also confusing
and somewhat inefficient (calling SeekableReadStream::pos
frequently), so this code has been refactored for clarity and to
improve efficiency by reducing the number of virtual calls. Error
detection has also been improved somewhat by ensuring that there
are enough bytes to read a block header, and that the step indexes
in the header are within the valid range.

Changed paths:
    audio/decoders/adpcm.cpp
    audio/decoders/adpcm_intern.h


diff --git a/audio/decoders/adpcm.cpp b/audio/decoders/adpcm.cpp
index ffb61a4..7f578dd 100644
--- a/audio/decoders/adpcm.cpp
+++ b/audio/decoders/adpcm.cpp
@@ -334,67 +334,89 @@ int MS_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
 
 #pragma mark -
 
-
-#define DK3_READ_NIBBLE() \
+#define DK3_READ_NIBBLE(channelNo) \
 do { \
 	if (_topNibble) { \
 		_nibble = _lastByte >> 4; \
 		_topNibble = false; \
 	} else { \
-		if (_stream->pos() >= _endpos) \
-			break; \
-		if ((_stream->pos() % _blockAlign) == 0) \
-			continue; \
 		_lastByte = _stream->readByte(); \
 		_nibble = _lastByte & 0xf; \
 		_topNibble = true; \
+		--blockBytesLeft; \
+		--audioBytesLeft; \
 	} \
-} while (0)
-
+	decodeIMA(_nibble, channelNo); \
+} while(0)
 
 int DK3_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
+	assert((numSamples % 4) == 0);
+
+	const uint startOffset = _stream->pos() % _blockAlign;
+	uint audioBytesLeft = _endpos - _stream->pos();
+	uint blockBytesLeft;
+	if (startOffset != 0) {
+		blockBytesLeft = _blockAlign - startOffset;
+	} else {
+		blockBytesLeft = 0;
+	}
+
 	int samples = 0;
+	while (samples < numSamples && audioBytesLeft) {
+		if (blockBytesLeft == 0) {
+			blockBytesLeft = MIN(_blockAlign, audioBytesLeft);
+			_topNibble = false;
 
-	assert((numSamples % 4) == 0);
+			if (blockBytesLeft < 16) {
+				warning("Truncated DK3 ADPCM block header");
+				break;
+			}
+
+			_stream->skip(2);
+			const uint16 rate = _stream->readUint16LE();
+			assert(rate == getRate());
+			_stream->skip(6);
 
-	while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
-		if ((_stream->pos() % _blockAlign) == 0) {
-			_stream->readUint16LE(); // Unknown
-			uint16 rate = _stream->readUint16LE(); // Copy of rate
-			_stream->skip(6); // Unknown
 			// Get predictor for both sum/diff channels
 			_status.ima_ch[0].last = _stream->readSint16LE();
 			_status.ima_ch[1].last = _stream->readSint16LE();
+
 			// Get index for both sum/diff channels
 			_status.ima_ch[0].stepIndex = _stream->readByte();
 			_status.ima_ch[1].stepIndex = _stream->readByte();
+			assert(_status.ima_ch[0].stepIndex < ARRAYSIZE(_imaTable));
+			assert(_status.ima_ch[1].stepIndex < ARRAYSIZE(_imaTable));
 
-			if (_stream->eos())
-				break;
-
-			// Sanity check
-			assert(rate == getRate());
+			blockBytesLeft -= 16;
+			audioBytesLeft -= 16;
 		}
 
-		DK3_READ_NIBBLE();
-		decodeIMA(_nibble, 0);
+		DK3_READ_NIBBLE(0);
+		DK3_READ_NIBBLE(1);
 
-		DK3_READ_NIBBLE();
-		decodeIMA(_nibble, 1);
+		*buffer++ = _status.ima_ch[0].last + _status.ima_ch[1].last;
+		*buffer++ = _status.ima_ch[0].last - _status.ima_ch[1].last;
 
-		buffer[samples++] = _status.ima_ch[0].last + _status.ima_ch[1].last;
-		buffer[samples++] = _status.ima_ch[0].last - _status.ima_ch[1].last;
+		DK3_READ_NIBBLE(0);
 
-		DK3_READ_NIBBLE();
-		decodeIMA(_nibble, 0);
+		*buffer++ = _status.ima_ch[0].last + _status.ima_ch[1].last;
+		*buffer++ = _status.ima_ch[0].last - _status.ima_ch[1].last;
 
-		buffer[samples++] = _status.ima_ch[0].last + _status.ima_ch[1].last;
-		buffer[samples++] = _status.ima_ch[0].last - _status.ima_ch[1].last;
+		samples += 4;
+
+		// if the last sample of a block ends on an odd byte, the encoder adds
+		// an extra alignment byte
+		if (!_topNibble && blockBytesLeft == 1) {
+			_stream->skip(1);
+			--blockBytesLeft;
+			--audioBytesLeft;
+		}
 	}
 
 	return samples;
 }
 
+#undef DK3_READ_NIBBLE
 
 #pragma mark -
 
diff --git a/audio/decoders/adpcm_intern.h b/audio/decoders/adpcm_intern.h
index f4a708c..4b7b348 100644
--- a/audio/decoders/adpcm_intern.h
+++ b/audio/decoders/adpcm_intern.h
@@ -229,20 +229,12 @@ private:
 // Based on FFmpeg's decoder and http://wiki.multimedia.cx/index.php?title=Duck_DK3_IMA_ADPCM
 
 class DK3_ADPCMStream : public Ima_ADPCMStream {
-protected:
-
-	void reset() {
-		Ima_ADPCMStream::reset();
-		_topNibble = false;
-	}
-
 public:
 	DK3_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
 		: Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
 
 		// DK3 only works as a stereo stream
 		assert(channels == 2);
-		_topNibble = false;
 	}
 
 	virtual int readBuffer(int16 *buffer, const int numSamples);


Commit: 10db6e9a44db071e75fd7e7882ebdd90e786af98
    https://github.com/scummvm/scummvm/commit/10db6e9a44db071e75fd7e7882ebdd90e786af98
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-09-09T23:29:58-05:00

Commit Message:
AUDIO: Mark SCI engine as using ADPCM

Changed paths:
    audio/decoders/adpcm.h


diff --git a/audio/decoders/adpcm.h b/audio/decoders/adpcm.h
index 353fd3b..0f0d83c 100644
--- a/audio/decoders/adpcm.h
+++ b/audio/decoders/adpcm.h
@@ -27,6 +27,7 @@
  *  - lastexpress
  *  - mohawk
  *  - saga
+ *  - sci (DK3 ADPCM for Phantasmagoria 2)
  *  - scumm
  *  - tinsel
  */





More information about the Scummvm-git-logs mailing list