[Scummvm-git-logs] scummvm master -> 0ab5e8544ee1d73daf3ff63c599a81eeb5d1526e

AndywinXp noreply at scummvm.org
Tue Aug 22 08:12:50 UTC 2023


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:
6fea29947f SCUMM: HE (Sound): Implement modding support for games using digital Miles audio
0ab5e8544e SCUMM: PJGAMES: Add support for modded audio


Commit: 6fea29947f3ba0bd80b03058a3d92c4febd7baf0
    https://github.com/scummvm/scummvm/commit/6fea29947f3ba0bd80b03058a3d92c4febd7baf0
Author: AndywinXp (andywinxp at gmail.com)
Date: 2023-08-22T10:12:09+02:00

Commit Message:
SCUMM: HE (Sound): Implement modding support for games using digital Miles audio

Changed paths:
    engines/scumm/he/mixer_he.cpp
    engines/scumm/he/mixer_he.h
    engines/scumm/he/sound_he.cpp
    engines/scumm/he/sound_he.h


diff --git a/engines/scumm/he/mixer_he.cpp b/engines/scumm/he/mixer_he.cpp
index 74f6d6be054..c76fce465d1 100644
--- a/engines/scumm/he/mixer_he.cpp
+++ b/engines/scumm/he/mixer_he.cpp
@@ -261,6 +261,16 @@ bool HEMixer::audioOverrideExists(int soundId, bool justGetInfo, int *duration,
 	return false;
 }
 
+void HEMixer::setSpoolingSongsTable(HESpoolingMusicItem *heSpoolingMusicTable, int32 tableSize) {
+	for (int i = 0; i < tableSize; i++) {
+		_offsetsToSongId.setVal(heSpoolingMusicTable[i].offset, heSpoolingMusicTable[i].song);
+	}
+}
+
+int32 HEMixer::matchOffsetToSongId(int32 offset) {
+	return _offsetsToSongId.getValOrDefault(offset, 0);
+}
+
 /* --- SOFTWARE MIXER --- */
 
 bool HEMixer::mixerInitMyMixerSubSystem() {
@@ -774,7 +784,7 @@ byte HEMixer::mixerGetOutputFlags() {
 
 void HEMixer::milesServiceAllStreams() {
 	for (int i = 0; i < MILES_MAX_CHANNELS; i++) {
-		if (_milesChannels[i]._stream.streamObj != nullptr)
+		if (_milesChannels[i]._stream.streamObj != nullptr && !_milesChannels[i]._isUsingStreamOverride)
 			_milesChannels[i].serviceStream();
 	}
 }
@@ -782,6 +792,60 @@ void HEMixer::milesServiceAllStreams() {
 void HEMixer::milesStartSpoolingChannel(int channel, const char *filename, long offset, int flags, HESoundModifiers modifiers) {
 	assert(channel >= 0 && channel < ARRAYSIZE(_milesChannels));
 
+	if (_vm->_enableAudioOverride) {
+		int32 songId = matchOffsetToSongId(offset);
+
+		Audio::SeekableAudioStream *audioOverride = nullptr;
+		if (songId != 0 && audioOverrideExists(songId, false, nullptr, &audioOverride)) {
+			_milesChannels[channel]._playFlags = flags;
+			_milesChannels[channel]._bitsPerSample = 16;
+			_milesChannels[channel]._numChannels = audioOverride->isStereo() ? 2 : 1;
+			_milesChannels[channel]._dataOffset = offset;
+			_milesChannels[channel]._lastPlayPosition = 0;
+			_milesChannels[channel]._globType = 0;
+			_milesChannels[channel]._globNum = songId;
+			_milesChannels[channel]._modifiers.frequencyShift = modifiers.frequencyShift;
+			_milesChannels[channel]._modifiers.volume = modifiers.volume;
+			_milesChannels[channel]._modifiers.pan = modifiers.pan;
+			_milesChannels[channel]._baseFrequency = audioOverride->getRate();
+			_milesChannels[channel]._audioHandleActive = true; // Treat it as a sound effect since we're not streaming it in chunks
+			_milesChannels[channel]._isUsingStreamOverride = true;
+
+			bool shouldLoop = (_milesChannels[channel]._playFlags & CHANNEL_LOOPING);
+
+			if (shouldLoop) {
+				// Looping sounds don't care for modifiers!
+				_mixer->playStream(
+					Audio::Mixer::kMusicSoundType,
+					&_milesChannels[channel]._audioHandle,
+					Audio::makeLoopingAudioStream(audioOverride, 0),
+					channel,
+					255,
+					0,
+					DisposeAfterUse::NO);
+
+			} else {
+				int scaledPan = (modifiers.pan != 64) ? 2 * modifiers.pan - 127 : 0;
+				int newFrequency = (_milesChannels[channel]._baseFrequency * modifiers.frequencyShift) / HSND_SOUND_FREQ_BASE;
+				int msOffset = (offset * 1000) / newFrequency;
+				audioOverride->seek(msOffset);
+
+				_mixer->playStream(
+					Audio::Mixer::kMusicSoundType,
+					&_milesChannels[channel]._audioHandle,
+					audioOverride,
+					-1,
+					modifiers.volume,
+					scaledPan,
+					DisposeAfterUse::NO);
+
+				_mixer->setChannelRate(_milesChannels[channel]._audioHandle, newFrequency);
+			}
+
+			return;
+		}
+	}
+
 	if (channel >= 0 && channel < ARRAYSIZE(_milesChannels))
 		_milesChannels[channel].startSpoolingChannel(filename, offset, flags, modifiers, _mixer);
 }
@@ -798,6 +862,61 @@ bool HEMixer::milesStartChannel(int channel, int globType, int globNum, uint32 s
 	// is also going to trigger the appropriate callbacks
 	milesStopChannel(channel);
 
+	// Are there any audio overrides? If so, use a different codepath...
+	Audio::SeekableAudioStream *audioOverride = nullptr;
+	if (audioOverrideExists(globNum, false, nullptr, &audioOverride)) {
+
+		_milesChannels[channel]._playFlags = flags;
+		_milesChannels[channel]._bitsPerSample = 16;
+		_milesChannels[channel]._numChannels = audioOverride->isStereo() ? 2 : 1;
+		_milesChannels[channel]._dataOffset = offset;
+		_milesChannels[channel]._lastPlayPosition = 0;
+		_milesChannels[channel]._globType = globType;
+		_milesChannels[channel]._globNum = globNum;
+		_milesChannels[channel]._modifiers.frequencyShift = modifiers.frequencyShift;
+		_milesChannels[channel]._modifiers.volume = modifiers.volume;
+		_milesChannels[channel]._modifiers.pan = modifiers.pan;
+		_milesChannels[channel]._baseFrequency = audioOverride->getRate();
+		_milesChannels[channel]._audioHandleActive = true;
+		_mixerChannels[channel].isUsingStreamOverride = true;
+
+		Audio::Mixer::SoundType soundType =
+			globNum == HSND_TALKIE_SLOT ? Audio::Mixer::kSpeechSoundType : Audio::Mixer::kSFXSoundType;
+
+		bool shouldLoop = (_mixerChannels[channel].flags & CHANNEL_LOOPING);
+
+		if (shouldLoop) {
+			// Looping sounds don't care for modifiers!
+			_mixer->playStream(
+				soundType,
+				&_milesChannels[channel]._audioHandle,
+				Audio::makeLoopingAudioStream(audioOverride, 0),
+				channel,
+				255,
+				0,
+				DisposeAfterUse::NO);
+
+		} else {
+			int scaledPan = (modifiers.pan != 64) ? 2 * modifiers.pan - 127 : 0;
+			int newFrequency = (_milesChannels[channel]._baseFrequency * modifiers.frequencyShift) / HSND_SOUND_FREQ_BASE;
+			int msOffset = (offset * 1000) / newFrequency;
+			audioOverride->seek(msOffset);
+
+			_mixer->playStream(
+				soundType,
+				&_milesChannels[channel]._audioHandle,
+				audioOverride,
+				-1,
+				modifiers.volume,
+				scaledPan,
+				DisposeAfterUse::NO);
+
+			_mixer->setChannelRate(_milesChannels[channel]._audioHandle, newFrequency);
+		}
+
+		return true;
+	}
+
 	uint32 actualDataSize = 0;
 
 	// Fetch the audio format for the target sound, and fill out
@@ -990,8 +1109,8 @@ void HEMixer::milesStopAndCallback(int channel, int messageId) {
 			}
 		}
 	} else { // Streamed music
-		_mixer->stopHandle(_milesChannels[channel]._stream.streamHandle);
 		_milesChannels[channel]._stream.streamObj->finish();
+		_mixer->stopHandle(_milesChannels[channel]._stream.streamHandle);
 
 		if (_milesChannels[channel]._stream.fileHandle)
 			_milesChannels[channel]._stream.fileHandle->close();
@@ -1020,7 +1139,7 @@ void HEMixer::milesFeedMixer() {
 			soundDone = !_mixer->isSoundHandleActive(_milesChannels[i]._audioHandle);
 		}
 
-		if (_milesChannels[i]._stream.streamObj) {
+		if (_milesChannels[i]._stream.streamObj && !_milesChannels[i]._isUsingStreamOverride) {
 			soundDone |= _milesChannels[i]._stream.streamObj->endOfStream();
 			soundDone |= !_mixer->isSoundHandleActive(_milesChannels[i]._stream.streamHandle);
 		}
@@ -1263,6 +1382,8 @@ void HEMilesChannel::clearChannelData() {
 	_bitsPerSample = 8;
 	_numChannels = 1;
 	_dataFormat = WAVE_FORMAT_PCM;
+
+	_isUsingStreamOverride = false;
 }
 
 void HEMilesChannel::closeFileHandle() {
diff --git a/engines/scumm/he/mixer_he.h b/engines/scumm/he/mixer_he.h
index 36552365529..205290172cb 100644
--- a/engines/scumm/he/mixer_he.h
+++ b/engines/scumm/he/mixer_he.h
@@ -62,6 +62,7 @@ namespace Scumm {
 #define MILES_MAX_QUEUED_STREAMS              16
 
 struct HESoundModifiers;
+struct HESpoolingMusicItem;
 class ScummEngine_v60he;
 
 struct MilesModifiers {
@@ -99,6 +100,8 @@ public:
 	uint16 _bitsPerSample = 8;
 	uint16 _dataFormat = 1;
 
+	bool _isUsingStreamOverride = false;
+
 	HEMilesChannel() {
 		clearChannelData();
 	}
@@ -121,6 +124,7 @@ protected:
 	bool _useMilesSoundSystem = false;
 	bool _mixerPaused = false;
 	int _pauseCount = 0;
+	Common::HashMap<int32, int32> _offsetsToSongId;
 
 	HEMilesChannel _milesChannels[MILES_MAX_CHANNELS];
 
@@ -173,6 +177,9 @@ public:
 	bool audioOverrideExists(int globNum, bool justGetInfo,
 		int *duration = nullptr, Audio::SeekableAudioStream **outStream = nullptr);
 
+	void setSpoolingSongsTable(HESpoolingMusicItem *heSpoolingMusicTable, int32 tableSize);
+	int32 matchOffsetToSongId(int32 offset);
+
 	/* --- MILES MIXER CODE --- */
 	bool isMilesActive();
 	void milesStartSpoolingChannel(int channel, const char *filename, long offset, int flags, HESoundModifiers modifiers);
diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp
index deeba7aea04..e74e9a18a7a 100644
--- a/engines/scumm/he/sound_he.cpp
+++ b/engines/scumm/he/sound_he.cpp
@@ -523,6 +523,8 @@ void SoundHE::setupHEMusicFile() {
 							_heSpoolingMusicTable[i].offset,
 							_heSpoolingMusicTable[i].size);
 				}
+
+				_heMixer->setSpoolingSongsTable(_heSpoolingMusicTable, _heSpoolingMusicCount);
 			} else {
 				debug(5, "setupHEMusicFile(): Can't allocate table for spooling music file '%s'", musicFilename.c_str());
 			}
diff --git a/engines/scumm/he/sound_he.h b/engines/scumm/he/sound_he.h
index e494f5dd6dc..e24a99d50d4 100644
--- a/engines/scumm/he/sound_he.h
+++ b/engines/scumm/he/sound_he.h
@@ -132,10 +132,21 @@ struct HESoundModifiers {
 	int volume;
 };
 
+
+struct HESpoolingMusicItem {
+	int32 song;
+	int32 offset;
+	int32 size;
+
+	char filename[128];
+};
+
 class ScummEngine_v60he;
 class HEMixer;
 
 class SoundHE : public Sound {
+	friend class HEMixer;
+
 protected:
 	ScummEngine_v60he *_vm;
 
@@ -150,13 +161,6 @@ protected:
 	};
 	HESoundCallbackItem _soundCallbackScripts[HSND_MAX_CALLBACK_SCRIPTS];
 
-	struct HESpoolingMusicItem {
-		int32 song;
-		int32 offset;
-		int32 size;
-
-		char filename[128];
-	};
 	HESpoolingMusicItem *_heSpoolingMusicTable;
 
 	struct PCMWaveFormat {


Commit: 0ab5e8544ee1d73daf3ff63c599a81eeb5d1526e
    https://github.com/scummvm/scummvm/commit/0ab5e8544ee1d73daf3ff63c599a81eeb5d1526e
Author: AndywinXp (andywinxp at gmail.com)
Date: 2023-08-22T10:12:45+02:00

Commit Message:
SCUMM: PJGAMES: Add support for modded audio

Feature request #14265 from the tracker.

Changed paths:
    engines/scumm/detection_tables.h


diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index b4f6bc4a506..357c9f79e4b 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -346,7 +346,7 @@ static const GameSettings gameVariantsTable[] = {
 	{"freddicove", "HE 100", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO4(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT, GUIO_AUDIO_OVERRIDE)},
 
 	// Restructured the Scumm engine
-	{"pjgames", 0, 0, GID_PJGAMES, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+	{"pjgames", 0, 0, GID_PJGAMES, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO4(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT, GUIO_AUDIO_OVERRIDE)},
 
 	// Added the use of bink videos
 	{"Soccer2004", 0, 0, GID_SOCCER2004, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},




More information about the Scummvm-git-logs mailing list