[Scummvm-git-logs] scummvm master -> 510b9737492ff98dcf891fd8a14367435b9e5ecf

bluegr noreply at scummvm.org
Tue Dec 24 09:38:13 UTC 2024


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

Summary:
aa553c0321 SCUMM: Remove superfluous protected keyword
510b973749 SCUMM: Initial work for injecting SE speech in classic MI1 and 2


Commit: aa553c0321a9e85d279bc0b8a2bebd09c7060752
    https://github.com/scummvm/scummvm/commit/aa553c0321a9e85d279bc0b8a2bebd09c7060752
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-24T11:36:11+02:00

Commit Message:
SCUMM: Remove superfluous protected keyword

Changed paths:
    engines/scumm/scumm.h


diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index b9f53d322ca..b5c470be7e9 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -993,7 +993,6 @@ protected:
 	void saveInfos(Common::WriteStream *file);
 	static bool loadInfos(Common::SeekableReadStream *file, SaveStateMetaInfos *stuff);
 
-protected:
 	/* Script VM - should be in Script class */
 	uint32 _localScriptOffsets[1024];
 	const byte *_scriptPointer = nullptr;


Commit: 510b9737492ff98dcf891fd8a14367435b9e5ecf
    https://github.com/scummvm/scummvm/commit/510b9737492ff98dcf891fd8a14367435b9e5ecf
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-24T11:36:12+02:00

Commit Message:
SCUMM: Initial work for injecting SE speech in classic MI1 and 2

TODOs:
- Correctly calculate the local script offset for all scripts
e.g. object scripts, such as Elaine's poster in the second screen)
- Handle multiple speech files for the same message
- Add handling for speech delay

Changed paths:
    engines/scumm/script_v5.cpp
    engines/scumm/scumm_v5.h
    engines/scumm/sound.cpp
    engines/scumm/soundse.cpp
    engines/scumm/soundse.h


diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 18a40cd948f..387ae57619f 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -1942,6 +1942,38 @@ void ScummEngine_v5::o5_pickupObject() {
 	runInventoryScript(1);
 }
 
+// Inject the speech from the SE version in the classic one, for MI1SE
+void ScummEngine_v5::injectMISESpeech() {
+	// TODOs:
+	// - Correctly calculate the local script offset for all scripts
+	//   (e.g. object scripts, such as Elaine's poster in the second screen)
+	// - Handle multiple speech files for the same message
+	// - Add handling for speech delay
+#if 0
+	if (_game.id == GID_MONKEY && (_game.features & GF_DOUBLEFINE_PAK)) {
+		uint16 currentScriptNum = vm.slot[_currentScript].number;
+		// Ignore texts from global scripts
+		if (currentScriptNum < _numGlobalScripts)
+			return;
+
+		// Ignore empty texts
+		if (!memcmp(_scriptPointer, "\xFF\x01\x0F\x00", 4) ||
+			!memcmp(_scriptPointer, "\xFF\x0F\x20\x00", 4) ||
+			!memcmp(_scriptPointer, "\xFE\x01\x0F\x04\x00", 5))
+			return;
+
+		// TODO: This isn't calculated correctly for all scripts
+		uint32 localOffset = _scriptPointer - _scriptOrgPointer - 1;
+		if (localOffset > _localScriptOffsets[currentScriptNum - _numGlobalScripts])
+			localOffset -= _localScriptOffsets[currentScriptNum - _numGlobalScripts];
+		// Construct a unique offset for each sound
+		uint32 offset = ((_currentRoom + currentScriptNum) << 16) | (localOffset & 0xFFFF);
+		_sound->talkSound(offset, 10, DIGI_SND_MODE_TALKIE);
+		//debug("injectMISESpeech: room %d, script %d, offset %d", _currentRoom, currentScriptNum, localOffset);
+	}
+#endif
+}
+
 void ScummEngine_v5::o5_print() {
 	// WORKAROUND bug #13374: The patched script for the Ultimate Talkie
 	// is missing a WaitForMessage() after Lemonhead says "Oooh, that's
@@ -1956,11 +1988,15 @@ void ScummEngine_v5::o5_print() {
 		return;
 	}
 
+	injectMISESpeech();
+
 	_actorToPrintStrFor = getVarOrDirectByte(PARAM_1);
 	decodeParseString();
 }
 
 void ScummEngine_v5::o5_printEgo() {
+	injectMISESpeech();
+
 	_actorToPrintStrFor = (byte)VAR(VAR_EGO);
 	decodeParseString();
 }
diff --git a/engines/scumm/scumm_v5.h b/engines/scumm/scumm_v5.h
index 2bed37ddeb1..0b90d7e2b8c 100644
--- a/engines/scumm/scumm_v5.h
+++ b/engines/scumm/scumm_v5.h
@@ -90,6 +90,8 @@ protected:
 
 	void walkActorToActor(int actor, int toActor, int dist);
 
+	void injectMISESpeech();
+
 	/**
 	 * Fetch the next script word, then if cond is *false*, perform a relative jump.
 	 * So this corresponds to a "jne" jump instruction.
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 2fd230e80ad..2bf5ac897cb 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -609,6 +609,20 @@ void Sound::startTalkSound(uint32 offset, uint32 length, int mode, Audio::SoundH
 			}
 		}
 		return;
+#if 0
+	} else if ((_vm->_game.features & GF_DOUBLEFINE_PAK) && (_vm->_game.id == GID_MONKEY || _vm->_game.id == GID_MONKEY2)) {
+		// MI1 and MI2 SE
+		if (_soundSE && !_soundsPaused && _mixer->isReady()) {
+			Audio::AudioStream *input = _soundSE->getAudioStream(
+				offset,
+				mode == DIGI_SND_MODE_SFX ? kSoundSETypeSFX : kSoundSETypeSpeech);
+
+			if (input)
+				_mixer->playStream((mode == DIGI_SND_MODE_SFX) ? Audio::Mixer::kSFXSoundType : Audio::Mixer::kSpeechSoundType, handle, input, id);
+		}
+
+		return;
+#endif
 	} else {
 		// This has been verified for INDY4, DOTT and SAM
 		if (_vm->_voiceMode == 2 && _vm->_game.version <= 6)
@@ -764,7 +778,7 @@ void Sound::startTalkSound(uint32 offset, uint32 length, int mode, Audio::SoundH
 		}
 
 		if (!_vm->_imuseDigital) {
-			if (mode == 1) {
+			if (mode == DIGI_SND_MODE_SFX) {
 				_mixer->playStream(Audio::Mixer::kSFXSoundType, handle, input, id);
 			} else {
 				_mixer->playStream(Audio::Mixer::kSpeechSoundType, handle, input, id);
diff --git a/engines/scumm/soundse.cpp b/engines/scumm/soundse.cpp
index f768f87244c..724f74cce6b 100644
--- a/engines/scumm/soundse.cpp
+++ b/engines/scumm/soundse.cpp
@@ -46,6 +46,7 @@ void SoundSE::initSoundFiles() {
 	switch (_vm->_game.id) {
 	case GID_MONKEY:
 	case GID_MONKEY2:
+		initAudioMappingMI();
 		_musicFilename = "MusicOriginal.xwb";
 		//_musicFilename = "MusicNew.xwb";	// TODO: allow toggle between original and new music
 		indexXWBFile(_musicFilename, &_musicEntries);
@@ -84,6 +85,11 @@ void SoundSE::initSoundFiles() {
 }
 
 Audio::SeekableAudioStream *SoundSE::getXWBTrack(int track) {
+	// TODO: Enable once WMA audio is implemented.
+	// Also, some of the PCM music tracks are not playing correctly
+	// (e.g. the act 1 track)
+	return nullptr;
+
 	Common::File *cdAudioFile = new Common::File();
 
 	if (!cdAudioFile->open(Common::Path(_musicFilename))) {
@@ -172,6 +178,24 @@ void SoundSE::indexXWBFile(const Common::String &filename, AudioIndex *audioInde
 		audioIndex->push_back(entry);
 	}
 
+	f->seek(segments[kXWBSegmentEntryNames].offset);
+
+	for (uint32 i = 0; i < entryCount; i++) {
+		Common::String name = f->readString(0, 64);
+		name.toLowercase();
+
+		(*audioIndex)[i].name = name;
+
+		if (!_audioNameToOriginalOffsetMap.contains(name)) {
+			// warning("indexXWBFile: name %s not found in speech.info", name.c_str());
+			continue;
+		}
+
+		const uint32 origOffset = _audioNameToOriginalOffsetMap[name];
+		_offsetToIndex[origOffset] = i;
+		// debug("indexXWBFile: %s -> offset %d, index %d", name.c_str(), origOffset, i);
+	}
+
 	f->close();
 	delete f;
 }
@@ -306,6 +330,43 @@ void SoundSE::indexFSBFile(const Common::String &filename, AudioIndex *audioInde
 #undef GET_FSB5_OFFSET
 #undef WARN_AND_RETURN_FSB
 
+void SoundSE::initAudioMappingMI() {
+	Common::File *f = new Common::File();
+	if (!f->open(Common::Path("speech.info"))) {
+		delete f;
+		return;
+	}
+
+	do {
+		AudioEntryMI entry;
+		entry.unk1 = f->readUint16LE();
+		entry.unk2 = f->readUint16LE();
+		entry.room = f->readUint16LE();
+		entry.script = f->readUint16LE();
+		entry.localScriptOffset = f->readUint16LE();
+		entry.messageIndex = f->readUint16LE();
+		entry.isEgoTalking = f->readUint16LE();
+		entry.wait = f->readUint16LE();
+		entry.textEnglish = f->readString(0, 256);
+		f->skip(256 * 4); // skip the rest of the text
+		entry.speechFile = f->readString(0, 32);
+		entry.speechFile.toLowercase();
+
+		//debug("unk1 %d, unk2 %d, room %d, script %d, localScriptOffset: %d, messageIndex %d, isEgoTalking: %d, wait: %d, textEnglish '%s', speechFile '%s'",
+		//	  entry.unk1, entry.unk2, entry.room, entry.script,
+		//	  entry.localScriptOffset, entry.messageIndex, entry.isEgoTalking, entry.wait,
+		//	  entry.textEnglish.c_str(), entry.speechFile.c_str());
+
+		uint32 offset = ((entry.room + entry.script) << 16) | (entry.localScriptOffset & 0xFFFF);
+		_audioNameToOriginalOffsetMap[entry.speechFile] = offset;
+
+		_audioEntriesMI.push_back(entry);
+	} while (!f->eos());
+
+	f->close();
+	delete f;
+}
+
 void SoundSE::initAudioMapping() {
 	ScummPAKFile *f = new ScummPAKFile(_vm);
 	_vm->openFile(*f, Common::Path("audiomapping.info"));
@@ -367,23 +428,32 @@ Audio::SeekableAudioStream *SoundSE::createSoundStream(Common::SeekableSubReadSt
 		delete stream;
 		return nullptr;
 	case kFSBCodecMP3:
+#ifdef USE_MAD
 		return Audio::makeMP3Stream(
 			stream,
 			DisposeAfterUse::YES
 		);
+#else
+		return nullptr;
+#endif
 	}
 
 	error("createSoundStream: Unknown XWB codec %d", entry.codec);
 }
 
 int32 SoundSE::getSoundIndexFromOffset(uint32 offset) {
-	// Some of the remastered sound offsets are off compared to the
-	// ones from the classic version, so we chop off the last 2 digits
-	const uint32 offsetToCheck = offset & 0xFFFFFF00;
+	uint32 offsetToCheck = offset;
+
+	if (_vm->_game.id == GID_TENTACLE) {
+		// Some of the remastered sound offsets are off compared to the
+		// ones from the classic version, so we chop off the last 2 digits
+		offsetToCheck = offset & 0xFFFFFF00;
+	}
+
 	if (_offsetToIndex.contains(offsetToCheck))
 		return _offsetToIndex[offsetToCheck];
-
-	return -1;
+	else
+		return -1;
 }
 
 Audio::AudioStream *SoundSE::getAudioStream(uint32 offset, SoundSEType type) {
diff --git a/engines/scumm/soundse.h b/engines/scumm/soundse.h
index a94052d3bb0..5edb5ba2cd2 100644
--- a/engines/scumm/soundse.h
+++ b/engines/scumm/soundse.h
@@ -99,8 +99,30 @@ private:
 	AudioIndex _sfxEntries;
 	Common::String _sfxFilename;
 
+	// Used in MI1 + MI2
+	struct AudioEntryMI {
+		uint16 unk1;
+		uint16 unk2;
+		uint16 room;
+		uint16 script;
+		uint16 localScriptOffset;
+		uint16 messageIndex;        // message index, used in messages split with wait()
+		uint16 isEgoTalking;        // 1 if ego is talking, 0 otherwise
+		uint16 wait;                // wait time in ms
+		Common::String textEnglish; // 256 bytes, English text
+		// 256 bytes, French text
+		// 256 bytes, Italian text
+		// 256 bytes, German text
+		// 256 bytes, Spanish text
+		Common::String speechFile; // 32 bytes
+	};
+
+	typedef Common::Array<AudioEntryMI> AudioIndexMI;
+	AudioIndexMI _audioEntriesMI;
+
 	int32 getSoundIndexFromOffset(uint32 offset);
 
+	void initAudioMappingMI();
 	void initAudioMapping();
 	void initSoundFiles();
 	void indexXWBFile(const Common::String &filename, AudioIndex *audioIndex);




More information about the Scummvm-git-logs mailing list