[Scummvm-git-logs] scummvm master -> 05cae5caf4c8682a50c00e23709d055f3ceee4d6
bluegr
noreply at scummvm.org
Tue Jan 7 01:38:31 UTC 2025
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
05cae5caf4 SCUMM: More cleanup and fixes for the MI1SE audio code
Commit: 05cae5caf4c8682a50c00e23709d055f3ceee4d6
https://github.com/scummvm/scummvm/commit/05cae5caf4c8682a50c00e23709d055f3ceee4d6
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2025-01-07T03:38:03+02:00
Commit Message:
SCUMM: More cleanup and fixes for the MI1SE audio code
Changed paths:
engines/scumm/script_v5.cpp
engines/scumm/scumm.h
engines/scumm/sound.cpp
engines/scumm/sound.h
engines/scumm/soundse.cpp
engines/scumm/soundse.h
engines/scumm/string.cpp
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 32581a8eafe..1932c53489e 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -1944,12 +1944,13 @@ void ScummEngine_v5::o5_pickupObject() {
// Inject the speech from the SE version in the classic one, for MI1SE.
void ScummEngine_v5::injectMISESpeech() {
- if (_game.id == GID_MONKEY && (_game.features & GF_DOUBLEFINE_PAK) && _sound->useRemasteredAudio()) {
- _currentScriptSavedForSpeechMI = vm.slot[_currentScript].number;
+ if (_sound->shouldInjectMISEAudio()) {
+ int32 currentScript = vm.slot[_currentScript].number;
+ int32 currentScriptOffset;
uint16 localScriptOffset;
- if (_currentScriptSavedForSpeechMI >= _numGlobalScripts) {
- int16 localScriptNumber = _currentScriptSavedForSpeechMI - _numGlobalScripts;
+ if (currentScript >= _numGlobalScripts) {
+ int16 localScriptNumber = currentScript - _numGlobalScripts;
if (localScriptNumber > 56)
localScriptOffset = 0;
else
@@ -1958,8 +1959,8 @@ void ScummEngine_v5::injectMISESpeech() {
localScriptOffset = 8;
}
- _currentScriptOffsetSavedForSpeechMI = vm.slot[_currentScript].offs - localScriptOffset;
- _currentSpeechIndexMI = 0;
+ currentScriptOffset = vm.slot[_currentScript].offs - localScriptOffset;
+ _sound->setupMISEAudioParams(currentScript, currentScriptOffset);
}
}
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 4ef6a75a38f..6cd834dc465 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -887,11 +887,6 @@ public:
int _NESStartStrip = 0;
- /* MI SE injected speech */
- int32 _currentScriptSavedForSpeechMI = 0;
- int32 _currentScriptOffsetSavedForSpeechMI = 0;
- int32 _currentSpeechIndexMI = 0;
-
protected:
int _curPalIndex = 0;
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 2255fae9706..8cdd7e6adf0 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -610,11 +610,11 @@ void Sound::startTalkSound(uint32 offset, uint32 length, int mode, Audio::SoundH
}
}
return;
- } else if ((_vm->_game.id == GID_MONKEY || _vm->_game.id == GID_MONKEY2) && (_vm->_game.features & GF_DOUBLEFINE_PAK) && _useRemasteredAudio) {
+ } else if (shouldInjectMISEAudio()) {
// MI1 and MI2 SE
if (_soundSE && !_soundsPaused && _mixer->isReady()) {
Audio::AudioStream *input = _soundSE->getAudioStream(
- _currentMISpeechIndex,
+ offset,
mode == DIGI_SND_MODE_SFX ? kSoundSETypeSFX : kSoundSETypeSpeech);
_digiSndMode |= mode;
@@ -625,8 +625,6 @@ void Sound::startTalkSound(uint32 offset, uint32 length, int mode, Audio::SoundH
else
_mixer->playStream(Audio::Mixer::kSpeechSoundType, handle, input, id);
}
-
- _vm->_currentSpeechIndexMI++;
}
return;
@@ -761,6 +759,7 @@ 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);
+ // Play remastered audio for DOTT
if (!input && _soundSE && _useRemasteredAudio) {
input = _soundSE->getAudioStream(
origOffset,
@@ -2193,16 +2192,27 @@ void Sound::updateMusicTimer() {
}
}
-void Sound::startRemasteredSpeech(const char *msgString, uint16 roomNumber, uint16 actorTalking, uint16 currentScriptNum, uint16 currentScriptOffset, uint16 numWaits) {
+void Sound::startRemasteredSpeech(const char *msgString, uint16 roomNumber, uint16 actorTalking, uint16 numWaits) {
// Crudely adapted from the disasm of MI1SE...
// TODO: Apply the various speech-line substitutions performed per-game
- int32 soundIndex = _soundSE->handleRemasteredSpeech(msgString, nullptr, roomNumber, actorTalking, currentScriptNum, currentScriptOffset, numWaits);
+ int32 soundIndex = _soundSE->handleRemasteredSpeech(
+ msgString,
+ nullptr,
+ roomNumber,
+ actorTalking,
+ numWaits
+ );
if (soundIndex >= 0) {
- _currentMISpeechIndex = soundIndex;
- talkSound(0, 0, DIGI_SND_MODE_TALKIE);
+ talkSound(soundIndex, 0, DIGI_SND_MODE_TALKIE);
}
}
+bool Sound::shouldInjectMISEAudio() const {
+ return (_vm->_game.id == GID_MONKEY || _vm->_game.id == GID_MONKEY2) &&
+ (_vm->_game.features & GF_DOUBLEFINE_PAK) &&
+ _useRemasteredAudio;
+}
+
} // End of namespace Scumm
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index cd44f1f3280..34d0957db2e 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -103,8 +103,6 @@ protected:
SoundSE *_soundSE = nullptr;
bool _useRemasteredAudio = false;
- int32 _currentMISpeechIndex = -1;
-
public:
Audio::SoundHandle *_talkChannelHandle; // Handle of mixer channel actor is talking on
@@ -152,8 +150,8 @@ public:
void updateMusicTimer();
- bool useRemasteredAudio() const { return _useRemasteredAudio; }
- void startRemasteredSpeech(const char *msgString, uint16 roomNumber, uint16 actorTalking, uint16 currentScriptNum, uint16 currentScriptOffset, uint16 numWaits);
+ bool shouldInjectMISEAudio() const;
+ void startRemasteredSpeech(const char *msgString, uint16 roomNumber, uint16 actorTalking, uint16 numWaits);
// TODO: Duplicate this in Sound as well?
bool isRolandLoom() const { return _soundCD->isRolandLoom(); }
@@ -173,6 +171,10 @@ public:
_soundCD->restoreCDAudioAfterLoad(info);
}
+ void setupMISEAudioParams(int32 scriptNum, int32 scriptOffset) {
+ _soundSE->setupMISEAudioParams(scriptNum, scriptOffset);
+ }
+
protected:
void setupSfxFile();
bool isSfxFinished() const;
diff --git a/engines/scumm/soundse.cpp b/engines/scumm/soundse.cpp
index d812da0a13a..644259317e3 100644
--- a/engines/scumm/soundse.cpp
+++ b/engines/scumm/soundse.cpp
@@ -50,12 +50,13 @@ void SoundSE::initSoundFiles() {
_musicFilename = "MusicOriginal.xwb";
//_musicFilename = "MusicNew.xwb"; // TODO: allow toggle between original and new music
indexXWBFile(_musicFilename, &_musicEntries);
- _sfxFilename = "SFXOriginal.xwb";
+ //_sfxFilename = "SFXOriginal.xwb";
//_sfxFilename = "SFXNew.xwb"; // TODO: allow toggle between original and new SFX
- indexXWBFile(_sfxFilename, &_sfxEntries);
+ //indexXWBFile(_sfxFilename, &_sfxEntries);
_speechFilename = "Speech.xwb";
indexXWBFile(_speechFilename, &_speechEntries);
- // TODO: iMUSEClient_Commentary.fsb
+ // TODO: ambience.xwb
+ // TODO: roomsfx.xwb
break;
case GID_TENTACLE:
initAudioMappingDOTTAndFT();
@@ -91,10 +92,8 @@ 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;
+ if (track < 0 || track >= _musicEntries.size())
+ return nullptr;
Common::File *cdAudioFile = new Common::File();
@@ -105,14 +104,14 @@ Audio::SeekableAudioStream *SoundSE::getXWBTrack(int track) {
AudioEntry entry = _musicEntries[track];
- auto subStream = new Common::SeekableSubReadStream(
+ Common::SeekableSubReadStream *subStream = new Common::SeekableSubReadStream(
cdAudioFile,
entry.offset,
entry.offset + entry.length,
DisposeAfterUse::YES
);
- return createSoundStream(subStream, entry);
+ return createSoundStream(subStream, entry, DisposeAfterUse::YES);
}
#define WARN_AND_RETURN_XWB(message) \
@@ -184,7 +183,21 @@ void SoundSE::indexXWBFile(const Common::String &filename, AudioIndex *audioInde
audioIndex->push_back(entry);
}
- const uint32 nameOffset = segments[kXWBSegmentEntryNames].offset;
+ uint32 nameOffset = segments[kXWBSegmentEntryNames].offset;
+ uint32 nameLen = 64;
+
+#if 0
+ if (_vm->_game.id == GID_MONKEY2) {
+ f->close();
+
+ // The audio file names of Monkey Island 2 SE are placed in a separate file
+ // TODO: These are read in the wrong order
+ f->open(Common::Path("speechcues.xsb"));
+ f->skip(42);
+ nameOffset = f->readUint32LE();
+ nameLen = Common::String::npos;
+ }
+#endif
if (!nameOffset)
WARN_AND_RETURN_XWB("XWB file does not contain audio file names")
@@ -192,7 +205,7 @@ void SoundSE::indexXWBFile(const Common::String &filename, AudioIndex *audioInde
f->seek(nameOffset);
for (uint32 i = 0; i < entryCount; i++) {
- Common::String name = f->readString(0, 64);
+ Common::String name = f->readString(0, nameLen);
name.toLowercase();
(*audioIndex)[i].name = name;
@@ -506,7 +519,7 @@ void SoundSE::initAudioMappingDOTTAndFT() {
delete f;
}
-Audio::SeekableAudioStream *SoundSE::createSoundStream(Common::SeekableSubReadStream *stream, AudioEntry entry) {
+Audio::SeekableAudioStream *SoundSE::createSoundStream(Common::SeekableSubReadStream *stream, AudioEntry entry, DisposeAfterUse::Flag disposeAfterUse) {
switch (entry.codec) {
case kXWBCodecPCM: {
byte flags = Audio::FLAG_LITTLE_ENDIAN;
@@ -514,7 +527,7 @@ Audio::SeekableAudioStream *SoundSE::createSoundStream(Common::SeekableSubReadSt
flags |= Audio::FLAG_16BITS;
if (entry.channels == 2)
flags |= Audio::FLAG_STEREO;
- return Audio::makeRawStream(stream, entry.rate, flags, DisposeAfterUse::YES);
+ return Audio::makeRawStream(stream, entry.rate, flags, disposeAfterUse);
}
case kXWBCodecXMA:
// Unused in MI1SE and MI2SE
@@ -523,7 +536,7 @@ Audio::SeekableAudioStream *SoundSE::createSoundStream(Common::SeekableSubReadSt
const uint32 blockAlign = (entry.align + 22) * entry.channels;
return Audio::makeADPCMStream(
stream,
- DisposeAfterUse::YES,
+ disposeAfterUse,
entry.length,
Audio::kADPCMMS,
entry.rate,
@@ -548,7 +561,7 @@ Audio::SeekableAudioStream *SoundSE::createSoundStream(Common::SeekableSubReadSt
#ifdef USE_MAD
return Audio::makeMP3Stream(
stream,
- DisposeAfterUse::YES
+ disposeAfterUse
);
#else
warning("createSoundStream: MP3 codec is not built in");
@@ -573,27 +586,27 @@ int32 SoundSE::getSoundIndexFromOffset(uint32 offset) {
return -1;
}
-SoundSE::AudioEntryMI *SoundSE::getAppropriateSpeechCue(const char *msgString, const char *speechFilenameSubstitution,
+int32 SoundSE::getAppropriateSpeechCue(const char *msgString, const char *speechFilenameSubstitution,
uint16 roomNumber, uint16 actorTalking, uint16 scriptNum, uint16 scriptOffset, uint16 numWaits) {
uint32 hash;
AudioEntryMI *curAudioEntry;
uint16 script;
int32 currentScore;
int32 bestScore;
- int bestScoreIdx;
+ int32 bestScoreIdx;
uint32 tmpHash;
hash = calculateStringHash(msgString);
tmpHash = hash;
if (!hash)
- return nullptr;
+ return -1;
bestScore = 0x40000000; // This is the score that we have to minimize...
bestScoreIdx = -1;
if (_audioEntriesMI.empty())
- return nullptr;
+ return -1;
for (uint curEntryIdx = 0; curEntryIdx < _audioEntriesMI.size(); curEntryIdx++) {
curAudioEntry = &_audioEntriesMI[curEntryIdx];
@@ -626,47 +639,42 @@ SoundSE::AudioEntryMI *SoundSE::getAppropriateSpeechCue(const char *msgString, c
}
if (currentScore < bestScore) {
bestScore = currentScore;
- bestScoreIdx = (int)curEntryIdx;
+ bestScoreIdx = (int32)curEntryIdx;
}
}
hash = tmpHash;
}
- if (bestScoreIdx == -1)
- return nullptr;
- else
- return &_audioEntriesMI[bestScoreIdx];
+
+ return bestScoreIdx;
}
Audio::AudioStream *SoundSE::getAudioStream(uint32 offset, SoundSEType type) {
Common::SeekableReadStream *stream;
Common::String audioFileName;
- AudioIndex &audioEntries = _musicEntries;
- int32 soundIndex = 0;
+ AudioEntry audioEntry = {};
+ int32 soundIndex = getSoundIndexFromOffset(offset);
+
+ if (soundIndex == -1) {
+ warning("getAudioStream: sound index not found for offset %d", offset);
+ return nullptr;
+ }
switch (type) {
case kSoundSETypeMusic:
audioFileName = _musicFilename;
- audioEntries = _musicEntries;
- soundIndex = getSoundIndexFromOffset(offset);
+ audioEntry = _musicEntries[soundIndex];
break;
case kSoundSETypeSpeech:
audioFileName = _speechFilename;
- audioEntries = _speechEntries;
- soundIndex = getSoundIndexFromOffset(offset);
+ audioEntry = _speechEntries[soundIndex];
break;
case kSoundSETypeSFX:
audioFileName = _sfxFilename;
- audioEntries = _sfxEntries;
- soundIndex = getSoundIndexFromOffset(offset);
+ audioEntry = _sfxEntries[soundIndex];
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;
@@ -683,7 +691,6 @@ Audio::AudioStream *SoundSE::getAudioStream(uint32 offset, SoundSEType type) {
}
}
- AudioEntry audioEntry = audioEntries[soundIndex];
Common::SeekableSubReadStream *subStream = new Common::SeekableSubReadStream(
stream,
audioEntry.offset,
@@ -691,7 +698,7 @@ Audio::AudioStream *SoundSE::getAudioStream(uint32 offset, SoundSEType type) {
DisposeAfterUse::YES
);
- return createSoundStream(subStream, audioEntry);
+ return createSoundStream(subStream, audioEntry, DisposeAfterUse::YES);
}
Common::String calculateCurrentString(const char *msgString) {
@@ -781,20 +788,21 @@ Common::String calculateCurrentString(const char *msgString) {
}
int32 SoundSE::handleRemasteredSpeech(const char *msgString, const char *speechFilenameSubstitution,
- uint16 roomNumber, uint16 actorTalking, uint16 scriptNum, uint16 scriptOffset, uint16 numWaits) {
+ uint16 roomNumber, uint16 actorTalking, uint16 numWaits) {
// Get the string without the various control codes and special characters...
Common::String currentString = calculateCurrentString(msgString);
- const AudioEntryMI *entry = getAppropriateSpeechCue(
+ const int32 entryIndex = getAppropriateSpeechCue(
currentString.c_str(),
speechFilenameSubstitution,
roomNumber, actorTalking,
- scriptNum,
- scriptOffset,
+ (uint16)_currentScriptSavedForSpeechMI,
+ (uint16)_currentScriptOffsetSavedForSpeechMI,
numWaits
);
- if (entry) {
+ if (entryIndex > 0 && entryIndex <= _audioEntriesMI.size()) {
+ const AudioEntryMI *entry = &_audioEntriesMI[entryIndex];
//debug("Selected entry: %s (%s)", entry->textEnglish.c_str(), entry->speechFile.c_str());
return _nameToIndex[entry->speechFile];
}
diff --git a/engines/scumm/soundse.h b/engines/scumm/soundse.h
index e6a6ed8769b..9ae8a0642a4 100644
--- a/engines/scumm/soundse.h
+++ b/engines/scumm/soundse.h
@@ -80,11 +80,9 @@ public:
const char *speechFilenameSubstitution,
uint16 roomNumber,
uint16 actorTalking,
- uint16 scriptNum,
- uint16 scriptOffset,
uint16 numWaits);
- AudioEntryMI *getAppropriateSpeechCue(const char *msgString,
+ int32 getAppropriateSpeechCue(const char *msgString,
const char *speechFilenameSubstitution,
uint16 roomNumber,
uint16 actorTalking,
@@ -92,6 +90,11 @@ public:
uint16 scriptOffset,
uint16 numWaits);
+ void setupMISEAudioParams(int32 scriptNum, int32 scriptOffset) {
+ _currentScriptSavedForSpeechMI = scriptNum;
+ _currentScriptOffsetSavedForSpeechMI = scriptOffset;
+ }
+
private:
enum AudioCodec {
kXWBCodecPCM = 0,
@@ -139,6 +142,10 @@ private:
typedef Common::Array<AudioEntryMI> AudioIndexMI;
AudioIndexMI _audioEntriesMI;
+ /* MI SE injected speech */
+ int32 _currentScriptSavedForSpeechMI = 0;
+ int32 _currentScriptOffsetSavedForSpeechMI = 0;
+
int32 getSoundIndexFromOffset(uint32 offset);
void initAudioMappingMI();
@@ -151,7 +158,7 @@ private:
// Index FSB audio files - used in DOTT and FT
void indexFSBFile(const Common::String &filename, AudioIndex *audioIndex);
- Audio::SeekableAudioStream *createSoundStream(Common::SeekableSubReadStream *stream, AudioEntry entry);
+ Audio::SeekableAudioStream *createSoundStream(Common::SeekableSubReadStream *stream, AudioEntry entry, DisposeAfterUse::Flag disposeAfterUse);
};
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index cb0ba8b2afc..804785badcf 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -1114,7 +1114,7 @@ void ScummEngine::displayDialog() {
if (_isRTL)
fakeBidiString(_charsetBuffer + _charsetBufPos, true, sizeof(_charsetBuffer) - _charsetBufPos);
- if ((_game.features & GF_DOUBLEFINE_PAK) && (_game.id == GID_MONKEY || _game.id == GID_MONKEY2) && _sound->useRemasteredAudio()) {
+ if (_sound->shouldInjectMISEAudio()) {
int numberOfWaits = countNumberOfWaits();
int32 currentActor = VAR_TALK_ACTOR != 0xFF ? VAR(VAR_TALK_ACTOR) : 0;
@@ -1123,8 +1123,6 @@ void ScummEngine::displayDialog() {
(const char *)&_charsetBuffer[_charsetBufPos],
(uint16)_currentRoom,
(uint16)currentActor,
- (uint16)_currentScriptSavedForSpeechMI,
- (uint16)_currentScriptOffsetSavedForSpeechMI,
(uint16)numberOfWaits);
}
More information about the Scummvm-git-logs
mailing list