[Scummvm-git-logs] scummvm master -> 6bfc9b11d575b69d8e04072629c600d28715438f

bluegr noreply at scummvm.org
Sun Dec 22 08:16:16 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:
277487dc7e SCUMM: Add support for the remastered speech and SFX of DOTT Remastered
6bfc9b11d5 NEWS: Mention support for the remastered speech and SFX in DOTT SE


Commit: 277487dc7eab8ae62fe7d7be5d5b4546cf0a145a
    https://github.com/scummvm/scummvm/commit/277487dc7eab8ae62fe7d7be5d5b4546cf0a145a
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-22T10:15:43+02:00

Commit Message:
SCUMM: Add support for the remastered speech and SFX of DOTT Remastered

Changed paths:
    engines/scumm/detection.h
    engines/scumm/detection_tables.h
    engines/scumm/metaengine.cpp
    engines/scumm/sound.cpp
    engines/scumm/sound.h
    engines/scumm/soundse.cpp
    engines/scumm/soundse.h


diff --git a/engines/scumm/detection.h b/engines/scumm/detection.h
index 2ff4a9f2bcf..ada809dcedf 100644
--- a/engines/scumm/detection.h
+++ b/engines/scumm/detection.h
@@ -36,6 +36,7 @@ namespace Scumm {
 #define GAMEOPTION_LOWLATENCYAUDIO                           GUIO_GAMEOPTIONS5
 #define GAMEOPTION_NETWORK                                   GUIO_GAMEOPTIONS6
 #define GAMEOPTION_COPY_PROTECTION                           GUIO_GAMEOPTIONS7
+#define GAMEOPTION_USE_REMASTERED_AUDIO                      GUIO_GAMEOPTIONS8
 
 /**
  * Descriptor of a specific SCUMM game. Used internally to store
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index cbe89be8f1f..5d64381fbd7 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -215,7 +215,7 @@ static const GameSettings gameVariantsTable[] = {
 	{"atlantis", "FM-TOWNS", 0, GID_INDY4,    5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO6(GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GAMEOPTION_TRIM_FMTOWNS_TO_200_PIXELS, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
 
 	{"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO3(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
-	{"tentacle", "SE", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY | GF_DOUBLEFINE_PAK, UNK, GUIO3(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
+	{"tentacle", "SE", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY | GF_DOUBLEFINE_PAK, UNK, GUIO4(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_USE_REMASTERED_AUDIO)},
 	{"tentacle", "Floppy", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO4(GUIO_NOSPEECH, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
 
 	{"samnmax",  "", 0, GID_SAMNMAX,  6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO3(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
diff --git a/engines/scumm/metaengine.cpp b/engines/scumm/metaengine.cpp
index b875ca1cd2e..ceb7b3cd86f 100644
--- a/engines/scumm/metaengine.cpp
+++ b/engines/scumm/metaengine.cpp
@@ -790,6 +790,15 @@ static const ExtraGuiOption mmDemoModeOption = {
 	0
 };
 
+static const ExtraGuiOption useRemasteredAudio = {
+	_s("Use remastered audio"),
+	_s("Use the remastered speech and sound effects."),
+	"use_remastered_audio",
+	true,
+	0,
+	0
+};
+
 const ExtraGuiOptions ScummMetaEngine::getExtraGuiOptions(const Common::String &target) const {
 	ExtraGuiOptions options;
 	// Query the GUI options
@@ -815,6 +824,9 @@ const ExtraGuiOptions ScummMetaEngine::getExtraGuiOptions(const Common::String &
 	if (target.empty() || guiOptions.contains(GAMEOPTION_AUDIO_OVERRIDE)) {
 		options.push_back(audioOverride);
 	}
+	if (target.empty() || guiOptions.contains(GAMEOPTION_USE_REMASTERED_AUDIO)) {
+		options.push_back(useRemasteredAudio);
+	}
 	if (target.empty() || gameid == "comi") {
 		options.push_back(comiObjectLabelsOption);
 
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index c81ff371b65..a7557d64a12 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -114,6 +114,8 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer, bool useReplacementAudioT
 			_hasFileBasedCDAudio = true;
 	}
 
+	_useRemasteredAudio = ConfMan.getBool("use_remastered_audio");
+
 	// This timer targets every talkie game, except for LOOM CD
 	// which is handled differently, and except for COMI which
 	// handles lipsync within Digital iMUSE.
@@ -937,6 +939,13 @@ void Sound::startTalkSound(uint32 offset, uint32 length, int mode, Audio::SoundH
 			if (mode == 2 && _vm->_game.id == GID_INDY4 && offset == 0x76ccbd4 && _vm->enhancementEnabled(kEnhGameBreakingBugFixes))
 				input = checkForBrokenIndy4Sample(file.release(), offset);
 
+			if (!input && _soundSE && _useRemasteredAudio) {
+				input = _soundSE->getAudioStream(
+					offset,
+					mode == DIGI_SND_MODE_SFX ? kSoundSETypeSFX : kSoundSETypeSpeech
+				);
+			}
+
 			if (!input) {
 				input = Audio::makeVOCStream(
 					file.release(),
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index ccc862006b6..dfdf6da978f 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -115,6 +115,7 @@ protected:
 	uint32 _replacementTrackStartTime;
 
 	SoundSE *_soundSE = nullptr;
+	bool _useRemasteredAudio = false;
 
 public:
 	Audio::SoundHandle *_talkChannelHandle;	// Handle of mixer channel actor is talking on
diff --git a/engines/scumm/soundse.cpp b/engines/scumm/soundse.cpp
index 54417e93cec..a4658c50854 100644
--- a/engines/scumm/soundse.cpp
+++ b/engines/scumm/soundse.cpp
@@ -57,6 +57,7 @@ void SoundSE::initSoundFiles() {
 		// TODO: iMUSEClient_Commentary.fsb
 		break;
 	case GID_TENTACLE:
+		initAudioMapping();
 		_musicFilename = "iMUSEClient_Music.fsb";
 		indexFSBFile(_musicFilename, &_musicEntries);
 		_sfxFilename = "iMUSEClient_SFX.fsb";
@@ -209,6 +210,11 @@ void SoundSE::indexFSBFile(const Common::String &filename, AudioIndex *audioInde
 	const uint32 nameOffset = sampleHeaderSize + headerSize;
 	const uint32 baseOffset = headerSize + sampleHeaderSize + nameSize;
 
+	uint64 pos = f->pos();
+	f->seek(nameOffset);
+	const uint32 firstNameOffset = nameOffset + f->readUint32LE();
+	f->seek(pos);
+
 	for (uint32 i = 0; i < sampleCount; i++) {
 		const uint32 origOffset = f->readUint32LE();
 		f->skip(4); // samples, used in XMA
@@ -252,6 +258,39 @@ void SoundSE::indexFSBFile(const Common::String &filename, AudioIndex *audioInde
 		audioIndex->push_back(entry);
 	}
 
+	f->seek(firstNameOffset);
+
+	for (uint32 i = 0; i < sampleCount; i++) {
+		Common::String name = f->readString();
+		name.toLowercase();
+
+		(*audioIndex)[i].name = name;
+
+		if (name.hasPrefix("ui_"))
+			continue;
+
+		// TODO: Support non-English audio files
+		if (name.hasPrefix("de_"))
+			continue;
+
+		if (!_audioNameToOriginalOffsetMap.contains(name)) {
+			if (name.hasPrefix("classic_"))
+				name = name.substr(8);
+
+			if (name.hasPrefix("en_") || name.hasPrefix("de_"))
+				name = name.substr(3);
+		}
+
+		if (!_audioNameToOriginalOffsetMap.contains(name)) {
+			//warning("indexFSBFile: name %s not found in audiomapping.info", name.c_str());
+			continue;
+		}
+
+		const uint32 origOffset = _audioNameToOriginalOffsetMap[name] & 0xFFFFFF00;
+		_offsetToIndex[origOffset] = i;
+		//debug("indexFSBFile: %s -> offset %d, index %d", name.c_str(), origOffset, i);
+	}
+
 	f->close();
 	delete f;
 }
@@ -259,6 +298,26 @@ void SoundSE::indexFSBFile(const Common::String &filename, AudioIndex *audioInde
 #undef GET_FSB5_OFFSET
 #undef WARN_AND_RETURN_FSB
 
+void SoundSE::initAudioMapping() {
+	ScummPAKFile *f = new ScummPAKFile(_vm);
+	_vm->openFile(*f, Common::Path("audiomapping.info"));
+
+	do {
+		const uint32 origOffset = f->readUint32LE();
+		Common::String name = f->readString(0, 64);
+		name.toLowercase();
+
+		if (f->eos())
+			break;
+		f->skip(4); // unknown
+
+		_audioNameToOriginalOffsetMap[name] = origOffset + 10;
+	} while (!f->eos());
+
+	f->close();
+	delete f;
+}
+
 Audio::SeekableAudioStream *SoundSE::createSoundStream(Common::SeekableSubReadStream *stream, AudioEntry entry) {
 	switch (entry.codec) {
 	case kXWBCodecPCM: {
@@ -307,47 +366,58 @@ Audio::SeekableAudioStream *SoundSE::createSoundStream(Common::SeekableSubReadSt
 	error("createSoundStream: Unknown XWB codec %d", entry.codec);
 }
 
-void SoundSE::startSoundEntry(int soundIndex, SoundSEType type) {
-	Common::SeekableReadStream *stream = nullptr;
-	Audio::SoundHandle *handle = nullptr;
-	Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType;
+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;
+	if (_offsetToIndex.contains(offsetToCheck))
+		return _offsetToIndex[offsetToCheck];
+
+	return -1;
+}
+
+Audio::AudioStream *SoundSE::getAudioStream(uint32 offset, SoundSEType type) {
+	Common::SeekableReadStream *stream;
 	Common::String audioFileName;
 	AudioIndex &audioEntries = _musicEntries;
+	int32 soundIndex = 0;
 
 	switch (type) {
 	case kSoundSETypeMusic:
-		handle = &_musicHandle;
-		soundType = Audio::Mixer::kMusicSoundType;
 		audioFileName = _musicFilename;
 		audioEntries = _musicEntries;
+		soundIndex = getSoundIndexFromOffset(offset);
 		break;
 	case kSoundSETypeSpeech:
-		handle = &_speechHandle;
-		soundType = Audio::Mixer::kSpeechSoundType;
 		audioFileName = _speechFilename;
 		audioEntries = _speechEntries;
+		soundIndex = getSoundIndexFromOffset(offset);
 		break;
 	case kSoundSETypeSFX:
-		handle = &_sfxHandle;
-		soundType = Audio::Mixer::kSFXSoundType;
 		audioFileName = _sfxFilename;
 		audioEntries = _sfxEntries;
+		soundIndex = getSoundIndexFromOffset(offset);
 		break;
 	}
 
+	if (soundIndex == -1) {
+		warning("getAudioStream: sound index not found for offset %d", offset);
+		return nullptr;
+	}
+
 	if (_vm->_game.id == GID_MONKEY || _vm->_game.id == GID_MONKEY2) {
 		Common::File *audioFile = new Common::File();
 		stream = audioFile;
 		if (!audioFile->open(Common::Path(audioFileName))) {
 			delete audioFile;
-			return;
+			return nullptr;
 		}
 	} else {
 		ScummPAKFile *audioFile = new ScummPAKFile(_vm);
 		stream = audioFile;
 		if (!_vm->openFile(*audioFile, Common::Path(audioFileName))) {
 			delete audioFile;
-			return;
+			return nullptr;
 		}
 	}
 
@@ -359,11 +429,7 @@ void SoundSE::startSoundEntry(int soundIndex, SoundSEType type) {
 		DisposeAfterUse::YES
 	);
 
-	_mixer->playStream(
-		soundType,
-		handle,
-		createSoundStream(subStream, audioEntry)
-	);
+	return createSoundStream(subStream, audioEntry);
 }
 
 } // End of namespace Scumm
diff --git a/engines/scumm/soundse.h b/engines/scumm/soundse.h
index 9bc48e6d60d..a94052d3bb0 100644
--- a/engines/scumm/soundse.h
+++ b/engines/scumm/soundse.h
@@ -55,8 +55,7 @@ public:
 	~SoundSE() = default;
 
 	Audio::SeekableAudioStream *getXWBTrack(int track);
-
-	void startSoundEntry(int soundIndex, SoundSEType type);
+	Audio::AudioStream *getAudioStream(uint32 offset, SoundSEType type);
 
 private:
 	enum AudioCodec {
@@ -83,22 +82,26 @@ private:
 		uint16 rate;
 		uint16 align;
 		byte bits;
+		Common::String name;
 	};
 
+	Common::HashMap<Common::String, uint32> _audioNameToOriginalOffsetMap;
+
 	typedef Common::Array<AudioEntry> AudioIndex;
+	typedef Common::HashMap<uint32, uint32> OffsetToIndexMap;
+
+	OffsetToIndexMap _offsetToIndex;
 
 	AudioIndex _musicEntries;
 	Common::String _musicFilename;
-	Audio::SoundHandle _musicHandle;
-
 	AudioIndex _speechEntries;
 	Common::String _speechFilename;
-	Audio::SoundHandle _speechHandle;
-
 	AudioIndex _sfxEntries;
 	Common::String _sfxFilename;
-	Audio::SoundHandle _sfxHandle;
 
+	int32 getSoundIndexFromOffset(uint32 offset);
+
+	void initAudioMapping();
 	void initSoundFiles();
 	void indexXWBFile(const Common::String &filename, AudioIndex *audioIndex);
 	Audio::SeekableAudioStream *createSoundStream(Common::SeekableSubReadStream *stream, AudioEntry entry);


Commit: 6bfc9b11d575b69d8e04072629c600d28715438f
    https://github.com/scummvm/scummvm/commit/6bfc9b11d575b69d8e04072629c600d28715438f
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-22T10:15:44+02:00

Commit Message:
NEWS: Mention support for the remastered speech and SFX in DOTT SE

Changed paths:
    NEWS.md


diff --git a/NEWS.md b/NEWS.md
index 48eda2eab0f..dd21290513a 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -11,6 +11,8 @@ For a more comprehensive changelog of the latest experimental code, see:
 
  SCUMM:
    - Added support for the classic SE variants of MI1, MI2, DOTT and FT.
+   - Added support for the remastered speech and sound effects in the
+     remastered version of Day of the Tentacle.
 
 
 #### 2.9.0 (2024-12-22)




More information about the Scummvm-git-logs mailing list