SCI: Add support for MOTHERGOOSE256 CD-Audio version

This multi-lingual version handles audio in a unique manner.
English audio is only on the CD audio track while the other
four languages are only in resource files. This is transparent
to the scripts that play audio; they're the same in all versions.
This required a custom interpreter that detects the language and
handles English differently. It even has a custom error message:
"You will not be able to play the 'ENGLISH' version."

Fixes bug #12431
This commit is contained in:
sluicebox 2021-04-24 00:35:03 -07:00
parent cf2392786b
commit 77b93c77ab
2 changed files with 29 additions and 7 deletions

View File

@ -164,10 +164,24 @@ reg_t kDoCdAudio(EngineState *s, int argc, reg_t *argv) {
* This is the SCI16 version; SCI32 is handled separately.
*/
reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) {
// JonesCD uses different functions based on the cdaudio.map file
// to use red book tracks.
if (g_sci->_features->usesCdTrack())
return kDoCdAudio(s, argc, argv);
// JonesCD and Mothergoose256 CD use different functions
// based on the cdaudio.map file to use red book tracks.
if (g_sci->_features->usesCdTrack()) {
if (g_sci->getGameId() == GID_MOTHERGOOSE256) {
// The CD audio version of Mothergoose256 CD is unique with a
// custom interpreter for its audio. English is only in the CD
// audio track while the other four languages are only in audio
// resource files. This is transparent to the scripts which are
// the same in all versions. The interpreter detected when
// English was selected and used CD audio in that case.
if (g_sci->getSciLanguage() == K_LANG_ENGLISH &&
argv[0].toUint16() != kSciAudioLanguage) {
return kDoCdAudio(s, argc, argv);
}
} else {
return kDoCdAudio(s, argc, argv);
}
}
Audio::Mixer *mixer = g_system->getMixer();
@ -264,6 +278,13 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) {
g_sci->getResMan()->setAudioLanguage(language);
kLanguage kLang = g_sci->getSciLanguage();
if (g_sci->_features->usesCdTrack() && language == K_LANG_ENGLISH) {
// Mothergoose 256 CD has a multi-lingual version with English only on CD audio,
// so setAudioLanguage() will fail because there are no English resource files.
// The scripts cycle through languages to test which are available for the main
// menu, so setting English must succeed. This was handled by a custom interpreter.
kLang = K_LANG_ENGLISH;
}
g_sci->setSciLanguage(kLang);
return make_reg(0, kLang);

View File

@ -517,7 +517,7 @@ int AudioPlayer::audioCdPlay(int track, int start, int duration) {
// ignores the data track and considers track 2 to be track 1.
return g_system->getAudioCDManager()->play(track - 1, 1, start, duration) ? 1 : 0;
} else {
// Jones in the Fast Lane CD Audio format
// Jones in the Fast Lane and Mothergoose256 CD Audio format
uint32 length = 0;
audioCdStop();
@ -528,14 +528,15 @@ int AudioPlayer::audioCdPlay(int track, int start, int duration) {
while (audioMap.pos() < audioMap.size()) {
uint16 res = audioMap.readUint16LE();
res &= 0x1fff; // Upper bits are always set in Mothergoose256
uint32 startFrame = audioMap.readUint16LE();
startFrame += audioMap.readByte() << 16;
audioMap.readByte(); // Unknown, always 0x20
audioMap.readByte(); // Unknown, always 0x20 in Jones, 0x04 in Mothergoose256
length = audioMap.readUint16LE();
length += audioMap.readByte() << 16;
audioMap.readByte(); // Unknown, always 0x00
// Jones uses the track as the resource value in the map
// The track is the resource value in the map
if (res == track) {
g_system->getAudioCDManager()->play(1, 1, startFrame, length);
_audioCdStart = g_system->getMillis();