[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