[Scummvm-git-logs] scummvm master -> 1380d40161dbaf93e87d1ea329fe15d56c7b2745
sev-
noreply at scummvm.org
Sun Jun 12 13:16:03 UTC 2022
This automated email contains information about 10 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
e70d636c50 TOON: Various fixes for Options and Main Menu
d3ded0e6ec TOON: Handle hotkeys and related animations in menus
cc89609e07 TOON: Do not allow disable speech and subtitles at the same time
41d4d4df3d TOON: Store textSpeed value and fix sound volume slider needle
e8791aba9e TOON: Mute music now works in intro main menu
6e444fe3ff TOON: Adjust movie volume to max of other sound type volumes
0a004da866 TOON: Fix comment mentioning up to 16 audio channel id
2db6be1038 TOON: Synch and persist game config with ConfMan properly
8dec0798f5 TOON: Fix click on Play to resume resulting in Drew walking
1380d40161 TOON: Don't display cutscene subtitles when text is OFF
Commit: e70d636c506537618eba3a759b4e4be16201b4e0
https://github.com/scummvm/scummvm/commit/e70d636c506537618eba3a759b4e4be16201b4e0
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-06-12T15:15:55+02:00
Commit Message:
TOON: Various fixes for Options and Main Menu
These bring them closer to the original behavior
Changes include:
- Proper sounds for buttons and switches
- Button clicking is effected in mouse down (not mouse up)
- A confirmation dialogue before quiting the game
- Button and slider animations in Options Menu (Main Menu has no button animations, just two frames)
- Reduced frequency of checking and updating a control's state
- (Demo) do not allow selection of middle Text option, which does not exist in Demo
- (Full Game) The text option dial now rotates towards the area clicked.
- Moving the mouse around while holding the left mouse button down affects at most one control (the selected one)
Changed paths:
engines/toon/toon.cpp
engines/toon/toon.h
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 5de479b71d3..7784e5e3acf 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -569,20 +569,20 @@ enum MainMenuMasks {
};
enum OptionMenuSelections {
- OPTIONMENUHOTSPOT_NONE = 0,
- OPTIONMENUHOTSPOT_PLAY = 1,
- OPTIONMENUHOTSPOT_QUIT = 2,
- OPTIONMENUHOTSPOT_TEXT = 3,
- OPTIONMENUHOTSPOT_TEXTSPEED = 4,
- OPTIONMENUHOTSPOT_VOLUMESFX = 5,
- OPTIONMENUHOTSPOT_VOLUMESFXSLIDER = 6,
- OPTIONMENUHOTSPOT_VOLUMEMUSIC = 7,
- OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER = 8,
- OPTIONMENUHOTSPOT_VOLUMEVOICE = 9,
- OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER = 10,
- OPTIONMENUHOTSPOT_SPEAKERBUTTON = 11,
- OPTIONMENUHOTSPOT_SPEAKERLEVER = 12,
- OPTIONMENUHOTSPOT_VIDEO_MODE = 13
+ OPTIONMENUHOTSPOT_NONE = 0,
+ OPTIONMENUHOTSPOT_PLAY = 1,
+ OPTIONMENUHOTSPOT_QUIT = 2,
+ OPTIONMENUHOTSPOT_TEXT = 3,
+ OPTIONMENUHOTSPOT_TEXTSPEED = 4,
+ OPTIONMENUHOTSPOT_VOLUMESFX = 5,
+ OPTIONMENUHOTSPOT_VOLUMESFXSLIDER = 6,
+ OPTIONMENUHOTSPOT_VOLUMEMUSIC = 7,
+ OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER = 8,
+ OPTIONMENUHOTSPOT_VOLUMEVOICE = 9,
+ OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER = 10,
+ OPTIONMENUHOTSPOT_SPEAKERBUTTON = 11,
+ OPTIONMENUHOTSPOT_SPEAKERLEVER = 12,
+ OPTIONMENUHOTSPOT_VIDEO_MODE = 13
};
enum OptionMenuMasks {
@@ -620,7 +620,7 @@ static const MenuFile optionMenuFiles[] = {
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_QUIT, "QUITBUTN.CAF", 0 }, // "Quit" button
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VIDEO_MODE, "VIDMODE.CAF", 0 }, // "Video mode" slider
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_TEXTSPEED, "TXTSPEED.CAF", 0 }, // "Text speed" slider
- { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_TEXT, "TEXTDIAL.CAF", 0}, // "Text" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_TEXT, "TEXTDIAL.CAF", 0 }, // "Text" button
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMESFX, "SFXBUTN.CAF", 0 }, // "SFX" button
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMESFXSLIDER, "SFXSLDR.CAF", 0 }, // "SFX volume" slider
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEVOICE, "VOICEBTN.CAF", 0 }, // "Voice" button
@@ -628,7 +628,7 @@ static const MenuFile optionMenuFiles[] = {
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEMUSIC, "MUSICBTN.CAF", 0 }, // "Music" button
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER, "MUSICSLD.CAF", 0 }, // "Music volume" button
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_SPEAKERBUTTON, "XTRABUTN.CAF", 0 }, // Right speaker button
- { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_SPEAKERLEVER, "XTRALEVR.CAF", 0}, // Left speaker switch
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_SPEAKERLEVER, "XTRALEVR.CAF", 0 }, // Left speaker switch
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "ANTENNAL.CAF", 6 }, // Decorative animation
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "ANTENNAR.CAF", 6 }, // Decorative animation
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "BIGREDL.CAF", 6 }, // Decorative animation
@@ -653,7 +653,7 @@ static const MenuFile optionMenuFilesEnglishDemo[] = {
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_QUIT, "QUITBUTN.CAF", 0 }, // "Quit" button
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VIDEO_MODE, "VIDMODE.CAF", 0 }, // "Video mode" slider
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_TEXTSPEED, "TXTSPEED.CAF", 0 }, // "Text speed" slider
- { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_TEXT, "TEXTDIAL.CAF", 0}, // "Text" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_TEXT, "TEXTDIAL.CAF", 0 }, // "Text" button
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMESFX, "SFXBUTN.CAF", 0 }, // "SFX" button
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMESFXSLIDER, "SFXSLDR.CAF", 0 }, // "SFX volume" slider
{ OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEVOICE, "VOICEBTN.CAF", 0 }, // "Voice" button
@@ -671,11 +671,12 @@ struct MenuEntry {
int animateOnFrame;
int animateCurFrame;
int activeFrame;
+ int targetFrame;
bool playOnce;
+ bool handled;
};
bool ToonEngine::showOptions() {
-
storePalette();
fadeOut(5);
Picture* optionPicture = new Picture(this);
@@ -690,31 +691,56 @@ bool ToonEngine::showOptions() {
_gameState->_mouseHidden = false;
// English demo options menu has less animations and no SFX
- int optionMenuEntryCount = _isEnglishDemo ? OPTIONMENU_ENTRYCOUNT_ENGLISH_DEMO : OPTIONMENU_ENTRYCOUNT;
+ const int optionMenuEntryCount = _isEnglishDemo ? OPTIONMENU_ENTRYCOUNT_ENGLISH_DEMO : OPTIONMENU_ENTRYCOUNT;
+
const MenuFile *optionMenuFilesPtr = _isEnglishDemo ? optionMenuFilesEnglishDemo : optionMenuFiles;
MenuEntry *entries = new MenuEntry[optionMenuEntryCount];
- for (int entryNr = 0; entryNr < optionMenuEntryCount; entryNr++) {
+ for (int entryNr = 0; entryNr < optionMenuEntryCount; ++entryNr) {
entries[entryNr].menuMask = optionMenuFilesPtr[entryNr].menuMask;
entries[entryNr].id = optionMenuFilesPtr[entryNr].id;
entries[entryNr].animation = new Animation(this);
entries[entryNr].animation->loadAnimation(optionMenuFilesPtr[entryNr].animationFile);
- if (entries[entryNr].id != OPTIONMENUHOTSPOT_NONE)
+ if (entries[entryNr].id != OPTIONMENUHOTSPOT_NONE) {
entries[entryNr].rect = entries[entryNr].animation->getRect();
+ // Bug fix for short hotspot rectangle for the text speed slider
+ // This bug is an original game bug.
+ // NOTE If low resolution mode is supported in the future,
+ // this height increment should be adjusted accordingly
+ if (entries[entryNr].id == OPTIONMENUHOTSPOT_TEXTSPEED)
+ entries[entryNr].rect.bottom += 10;
+
+ if (entries[entryNr].id == OPTIONMENUHOTSPOT_TEXT && !_isEnglishDemo) {
+ // For the game proper we need to extend the rectangle for the TEXT hotspot
+ // above and to the left and right, so that we can detect clicking on
+ // each of the labels around the dial.
+ // NOTE If low resolution mode is supported in the future,
+ // these rectangle dimensions should be adjusted accordingly
+ entries[entryNr].rect.top -= 20;
+ entries[entryNr].rect.left -= 65;
+ entries[entryNr].rect.right += 65;
+ }
+ }
entries[entryNr].animateOnFrame = optionMenuFilesPtr[entryNr].animateOnFrame;
entries[entryNr].animateCurFrame = 0;
entries[entryNr].activeFrame = 0;
+ entries[entryNr].targetFrame = -1;
entries[entryNr].playOnce = false;
+ entries[entryNr].handled = false;
}
- entries[10].activeFrame = _audioManager->_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) * (entries[10].animation->_numFrames - 1) / 256;
- entries[8].activeFrame = _audioManager->_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) * (entries[8].animation->_numFrames - 1) / 256;
- entries[6].activeFrame = _audioManager->_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) * (entries[6].animation->_numFrames - 1) / 256;
+ // Setting dial / option value in the game options menu
+ entries[10].activeFrame = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) * (entries[10].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
+ entries[8].activeFrame = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) * (entries[8].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
+ entries[6].activeFrame = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) * (entries[6].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
entries[9].activeFrame = _audioManager->isMusicMuted() ? 0 : 3;
entries[7].activeFrame = _audioManager->isVoiceMuted() ? 0 : 3;
entries[5].activeFrame = _audioManager->isSfxMuted() ? 0 : 3;
+ // TODO retrieve stored textSpeed value and set the needle indicator accordingly
+ entries[3].activeFrame = 0;
+
entries[2].activeFrame = entries[2].animation->_numFrames - 1;
if (!_showConversationText) {
@@ -734,17 +760,25 @@ bool ToonEngine::showOptions() {
int menuMask = OPTIONMENUMASK_EVERYWHERE;
int ratioX = 0;
- bool doExit = false;
+ int ratioY = 0;
+ bool doExitMenu = false;
bool exitGame = false;
+ bool targetFrameExceeded = false;
_gameState->_inMenu = true;
dirtyAllScreen();
_firstFrame = true;
- while (!doExit) {
+ int32 oldMouseX = _mouseX;
+ int32 oldMouseY = _mouseY;
+ int32 oldMouseButton = _mouseButton;
+ int targetVol;
+ Audio::Mixer::SoundType chosenSoundType;
+
+ while (!doExitMenu) {
int clickingOn = OPTIONMENUHOTSPOT_NONE;
int clickingOnSprite = 0;
- int clickRelease = false;
+ bool clickRelease = false;
while (!clickRelease) {
@@ -756,7 +790,8 @@ bool ToonEngine::showOptions() {
}
clearDirtyRects();
- for (int entryNr = 0; entryNr < optionMenuEntryCount; entryNr++) {
+ // Handle animations
+ for (int entryNr = 0; entryNr < optionMenuEntryCount; ++entryNr) {
if (entries[entryNr].menuMask & menuMask) {
int animPosX = 0;
int animPosY = 0;
@@ -765,7 +800,7 @@ bool ToonEngine::showOptions() {
if (sparkleDelay > 0) {
// Don't show the next sparkle until the delay has
// counted down.
- sparkleDelay--;
+ --sparkleDelay;
continue;
} else if (entries[entryNr].animateCurFrame == 0 && entries[entryNr].activeFrame == 0) {
// Start of a new sparkle animation. Generate a
@@ -776,202 +811,299 @@ bool ToonEngine::showOptions() {
animPosX = sparklePosX;
animPosY = sparklePosY;
}
- if (entries[entryNr].animateOnFrame) {
- entries[entryNr].animateCurFrame++;
+ if (entries[entryNr].animateOnFrame) { // animateOnFrame is used to slow down an animation
+ ++entries[entryNr].animateCurFrame; // counter towards animateOnFrame
if (entries[entryNr].animateOnFrame <= entries[entryNr].animateCurFrame) {
- entries[entryNr].activeFrame++;
- if (entries[entryNr].activeFrame >= entries[entryNr].animation->_numFrames) {
- entries[entryNr].activeFrame = 0;
- if (entries[entryNr].playOnce) {
+
+ if (entries[entryNr].targetFrame >= 0) {
+ if (entries[entryNr].targetFrame >= entries[entryNr].animation->_numFrames) {
+ entries[entryNr].targetFrame = entries[entryNr].animation->_numFrames - 1;
+ }
+ targetFrameExceeded = false;
+ if (entries[entryNr].activeFrame <= entries[entryNr].targetFrame) {
+ ++entries[entryNr].activeFrame;
+ if (entries[entryNr].activeFrame > entries[entryNr].targetFrame)
+ targetFrameExceeded = true;
+ } else if (entries[entryNr].activeFrame >= entries[entryNr].targetFrame) {
+ --entries[entryNr].activeFrame;
+ if (entries[entryNr].activeFrame < entries[entryNr].targetFrame)
+ targetFrameExceeded = true;
+ }
+
+ if (targetFrameExceeded) {
entries[entryNr].animateOnFrame = 0;
- entries[entryNr].playOnce = false;
+ entries[entryNr].activeFrame = entries[entryNr].targetFrame;
+ entries[entryNr].targetFrame = -1;
+
+ if (entries[entryNr].id == OPTIONMENUHOTSPOT_PLAY) { // PLAY BUTTON
+ exitGame = false;
+ doExitMenu = true;
+ }
+
+ if (entries[entryNr].id == OPTIONMENUHOTSPOT_QUIT) { // QUIT BUTTON
+ exitGame = showQuitConfirmationDialogue();
+ if (exitGame) {
+ doExitMenu = true;
+ } else {
+ entries[entryNr].activeFrame = 0;
+ }
+ }
+ }
+ } else {
+ ++entries[entryNr].activeFrame;
+ if (!_isEnglishDemo && entries[entryNr].activeFrame == 3) {
+ if (entryNr == 19) {
+ // The left (SPEECH test) horn has 7 frames.
+ // Frame 3 works best to play the Burp Speech sound
+ _audioManager->playVoice(316, true);
+ } else if (entryNr == 20) {
+ // The right (SFX test) horn has 7 frames.
+ // Frame 3 works best to play the Bell SFX sound
+ playSFX(-3, 128);
+ }
}
- if (entryNr == 20 && entries[entryNr].animateOnFrame > 0) {
- playSFX(-3, 128);
+ if (entries[entryNr].activeFrame >= entries[entryNr].animation->_numFrames) {
+ entries[entryNr].activeFrame = 0;
+ if (_isEnglishDemo && entryNr == 11) {
+ // Sparkle animation has finished. Generate
+ // a random delay until the next sparkle.
+ sparkleDelay = randRange(0, 100);
+ }
+ if (entries[entryNr].playOnce) {
+ entries[entryNr].animateOnFrame = 0;
+ entries[entryNr].playOnce = false;
+ }
}
- if (_isEnglishDemo && entryNr == 11)
- // Sparkle animation has finished. Generate
- // a random delay until the next sparkle.
- sparkleDelay = randRange(0, 100);
}
entries[entryNr].animateCurFrame = 0;
}
}
- int32 frameNr = entries[entryNr].activeFrame;
- entries[entryNr].animation->drawFrame(*_mainSurface, frameNr, animPosX, animPosY);
+ entries[entryNr].animation->drawFrame(*_mainSurface, entries[entryNr].activeFrame, animPosX, animPosY);
}
}
- parseInput();
+ oldMouseX = _mouseX;
+ oldMouseY = _mouseY;
+ oldMouseButton = _mouseButton;
- copyToVirtualScreen(true);
- if (_firstFrame) {
- _firstFrame = false;
- fadeIn(5);
- }
- _system->delayMillis(17);
+ // update mouse clicking state
+ parseInput();
- if (_mouseButton & 1) {
- // left mouse button pushed down
+ // NOTE Placing the code here seems to mitigate the issue
+ // of clicking Play to resume playing and Drew moving to
+ // that spot in-game.
+ // It still happens if mouse button is held down.
+ if (_shouldQuit || doExitMenu) {
clickingOn = OPTIONMENUHOTSPOT_NONE;
- for (int entryNr = 0; entryNr < optionMenuEntryCount; entryNr++) {
- if (entries[entryNr].menuMask & menuMask) {
- if (entries[entryNr].id != OPTIONMENUHOTSPOT_NONE) {
- if (entries[entryNr].rect.contains(_mouseX, _mouseY)) {
+ clickRelease = true;
+ doExitMenu = true;
+ } else {
+ copyToVirtualScreen(true);
+ if (_firstFrame) {
+ _firstFrame = false;
+ fadeIn(5);
+ }
+ _system->delayMillis(17);
+
+ // Avoid unnecessary checks and actions if mouse has not moved or changed status
+ if (oldMouseButton != _mouseButton
+ || ((_mouseButton & 1)
+ && (oldMouseX != _mouseX || oldMouseY != _mouseY))) {
+ if (_mouseButton & 1) {
+ // left mouse button pressed
+ for (int entryNr = 0; entryNr < optionMenuEntryCount; ++entryNr) {
+ if (entries[entryNr].menuMask & menuMask
+ && entries[entryNr].id != OPTIONMENUHOTSPOT_NONE
+ && entries[entryNr].rect.contains(_mouseX, _mouseY)
+ && ((clickingOn == OPTIONMENUHOTSPOT_NONE && !(oldMouseButton & 1))
+ || (clickingOn == entries[entryNr].id && !entries[entryNr].handled))) {
clickingOn = entries[entryNr].id;
clickingOnSprite = entryNr;
+ // Note, due to how rect.contains() is implemented,
+ // the difference (_mouseX - entries[entryNr].rect.left)
+ // will always be lower than entries[entryNr].rect.width()
+ // and thus ratioX will always be lower than 256.
+ // This is intentional.
ratioX = (_mouseX - entries[entryNr].rect.left) * 256 / entries[entryNr].rect.width();
+ ratioY = (_mouseY - entries[entryNr].rect.top) * 256 / entries[entryNr].rect.height();
+ break;
}
}
+ } else if (clickingOn != OPTIONMENUHOTSPOT_NONE) {
+ // left mouse button released/not pushed down
+ clickRelease = true;
+ clickingOn = OPTIONMENUHOTSPOT_NONE;
+ entries[clickingOnSprite].handled = false;
}
- }
- } else {
- // left mouse button released/not pushed down
- if (clickingOn != OPTIONMENUHOTSPOT_NONE)
- clickRelease = true;
- }
-
- // handle sliders
- if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER) {
- entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
- int vol = entries[clickingOnSprite].activeFrame * 256 / entries[clickingOnSprite].animation->_numFrames;
- _audioManager->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol);
- }
-
- if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER) {
- entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
- int vol = entries[clickingOnSprite].activeFrame * 256 / entries[clickingOnSprite].animation->_numFrames;
- _audioManager->_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol);
- }
-
- if (clickingOn == OPTIONMENUHOTSPOT_VOLUMESFXSLIDER) {
- entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
- int vol = entries[clickingOnSprite].activeFrame * 256 / entries[clickingOnSprite].animation->_numFrames;
- _audioManager->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol);
- }
-
- if (clickingOn == OPTIONMENUHOTSPOT_TEXTSPEED) {
- entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
- }
-
- if (clickingOn == OPTIONMENUHOTSPOT_PLAY) {
- entries[0].activeFrame = entries[0].animation->_numFrames - 1;
- } else {
- entries[0].activeFrame = 0;
- }
-
- if (clickingOn == OPTIONMENUHOTSPOT_QUIT) {
- entries[1].activeFrame = entries[1].animation->_numFrames - 1;
- } else {
- entries[1].activeFrame = 0;
- }
-
- if (_shouldQuit) {
- clickingOn = OPTIONMENUHOTSPOT_NONE;
- clickRelease = true;
- doExit = true;
- }
- }
-
- if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSIC) {
- if (entries[9].activeFrame == 0) {
- entries[9].activeFrame = 3;
- _audioManager->muteMusic(false);
- } else {
- entries[9].activeFrame = 0;
- _audioManager->muteMusic(true);
- }
- if (!_isEnglishDemo)
- playSFX(-7, 128);
- }
-
- if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICE) {
- if (entries[7].activeFrame == 0) {
- entries[7].activeFrame = 3;
- _audioManager->muteVoice(false);
- } else {
- entries[7].activeFrame = 0;
- _audioManager->muteVoice(true);
- }
- if (!_isEnglishDemo)
- playSFX(-7, 128);
- }
- if (clickingOn == OPTIONMENUHOTSPOT_VOLUMESFX) {
- if (entries[5].activeFrame == 0) {
- entries[5].activeFrame = 3;
- _audioManager->muteSfx(false);
- } else {
- entries[5].activeFrame = 0;
- _audioManager->muteSfx(true);
- }
- if (!_isEnglishDemo)
- playSFX(-7, 128);
- }
+ // handle sliders
+ switch (clickingOn) {
+ case OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER:
+ // fall through
+ case OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER:
+ // fall through
+ case OPTIONMENUHOTSPOT_VOLUMESFXSLIDER:
+ entries[clickingOnSprite].targetFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
+ entries[clickingOnSprite].animateOnFrame = 1;
+ entries[clickingOnSprite].playOnce = true;
+
+ targetVol = entries[clickingOnSprite].targetFrame * Audio::Mixer::kMaxMixerVolume / (entries[clickingOnSprite].animation->_numFrames - 1);
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER)
+ chosenSoundType = Audio::Mixer::kMusicSoundType;
+ else if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER)
+ chosenSoundType = Audio::Mixer::kSpeechSoundType;
+ else
+ chosenSoundType = Audio::Mixer::kSFXSoundType;
+ _mixer->setVolumeForSoundType(chosenSoundType, targetVol);
+ break;
- if (clickingOn == OPTIONMENUHOTSPOT_SPEAKERBUTTON) {
- entries[11].animateOnFrame = 4;
- entries[11].playOnce = true;
+ case OPTIONMENUHOTSPOT_TEXTSPEED:
+ entries[clickingOnSprite].targetFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
+ entries[clickingOnSprite].animateOnFrame = 1;
+ entries[clickingOnSprite].playOnce = true;
+ // TODO store textSpeed
+ break;
- entries[19].animateOnFrame = 4;
- entries[19].playOnce = true;
+ default:
+ break;
+ }
- playSFX(-10, 128);
- if (!_isEnglishDemo)
- _audioManager->playVoice(316, true);
- }
+ // handle buttons
+ if (clickingOn != OPTIONMENUHOTSPOT_NONE && !entries[clickingOnSprite].handled) {
+ switch (clickingOn) {
+ case OPTIONMENUHOTSPOT_PLAY:
+ // fall through
+ case OPTIONMENUHOTSPOT_QUIT:
+ entries[clickingOnSprite].handled = true;
+ entries[clickingOnSprite].targetFrame = entries[clickingOnSprite].animation->_numFrames - 1;
+ entries[clickingOnSprite].animateOnFrame = 1;
+ entries[clickingOnSprite].playOnce = true;
+ if (!_isEnglishDemo) {
+ if (clickingOn == OPTIONMENUHOTSPOT_PLAY)
+ playSFX(-7, 128);
+ else
+ playSFX(-8, 128);
+ }
+ break;
+
+ case OPTIONMENUHOTSPOT_VOLUMEMUSIC:
+ // fall through
+ case OPTIONMENUHOTSPOT_VOLUMEVOICE:
+ // fall through
+ case OPTIONMENUHOTSPOT_VOLUMESFX:
+ entries[clickingOnSprite].handled = true;
+ if (entries[clickingOnSprite].activeFrame == 0) {
+ entries[clickingOnSprite].targetFrame = entries[clickingOnSprite].animation->_numFrames - 1;
+ entries[clickingOnSprite].animateOnFrame = 1;
+ entries[clickingOnSprite].playOnce = true;
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSIC)
+ _audioManager->muteMusic(false);
+ else if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICE)
+ _audioManager->muteVoice(false);
+ else
+ _audioManager->muteSfx(false);
+ } else {
+ entries[clickingOnSprite].targetFrame = 0;
+ entries[clickingOnSprite].animateOnFrame = 1;
+ entries[clickingOnSprite].playOnce = true;
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSIC)
+ _audioManager->muteMusic(true);
+ else if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICE)
+ _audioManager->muteVoice(true);
+ else
+ _audioManager->muteSfx(true);
+ }
+ if (!_isEnglishDemo)
+ playSFX(-7, 128);
+ break;
+
+ case OPTIONMENUHOTSPOT_SPEAKERBUTTON:
+ entries[clickingOnSprite].handled = true;
+ entries[clickingOnSprite].animateOnFrame = 4;
+ entries[clickingOnSprite].playOnce = true;
+
+ entries[19].animateOnFrame = 4;
+ entries[19].playOnce = true;
+
+ if (!_isEnglishDemo)
+ playSFX(-10, 128);
+ break;
+
+ case OPTIONMENUHOTSPOT_SPEAKERLEVER:
+ entries[clickingOnSprite].handled = true;
+ // Speaker lever animation has 2 frames (on and off position).
+ // Set the activeFrame to the other position than the current one.
+ entries[clickingOnSprite].activeFrame = entries[clickingOnSprite].activeFrame ? 0 : 1;
+ if (entries[clickingOnSprite].activeFrame == 1) {
+ entries[20].animateOnFrame = 4;
+ entries[20].playOnce = false;
+ } else {
+ entries[20].playOnce = true;
+ }
+ if (!_isEnglishDemo)
+ playSFX(-10, 128);
+ break;
+
+ case OPTIONMENUHOTSPOT_TEXT:
+ entries[clickingOnSprite].handled = true;
+ if (!_isEnglishDemo) {
+ if ((ratioY <= 151 && ratioX >= 88 && ratioX <= 169)
+ || (ratioY > 151 && ratioX >= 122 && ratioX <= 145) ) {
+ _showConversationText = false;
+ entries[clickingOnSprite].targetFrame = 4;
+ entries[clickingOnSprite].animateOnFrame = 1;
+ entries[clickingOnSprite].playOnce = true;
+ } else if (ratioY > 151 && ratioX > 145) {
+ _showConversationText = true;
+ setFont(true);
+ entries[clickingOnSprite].targetFrame = 8;
+ entries[clickingOnSprite].animateOnFrame = 1;
+ entries[clickingOnSprite].playOnce = true;
+ } else if (ratioY > 151 && ratioX < 122) {
+ _showConversationText = true;
+ setFont(false);
+ entries[clickingOnSprite].targetFrame = 0;
+ entries[clickingOnSprite].animateOnFrame = 1;
+ entries[clickingOnSprite].playOnce = true;
+ }
+ playSFX(-9, 128);
+ } else {
+ // In the demo, the behavior is different:
+ // Clicking anywhere in the Text Dial hotspot
+ // toggles between "Text Off" and "Text On"
+ switch (entries[clickingOnSprite].activeFrame) {
+ case 0:
+ _showConversationText = true;
+ entries[clickingOnSprite].targetFrame = 8;
+ entries[clickingOnSprite].animateOnFrame = 1;
+ entries[clickingOnSprite].playOnce = true;
+ break;
+
+ case 8:
+ _showConversationText = false;
+ entries[clickingOnSprite].targetFrame = 0;
+ entries[clickingOnSprite].animateOnFrame = 1;
+ entries[clickingOnSprite].playOnce = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
- if (clickingOn == OPTIONMENUHOTSPOT_SPEAKERLEVER) {
+ // don't allow change to video mode
+ case OPTIONMENUHOTSPOT_VIDEO_MODE:
+ entries[clickingOnSprite].handled = true;
+ playSoundWrong();
+ break;
- entries[12].activeFrame = 1 - entries[12].activeFrame;
- if(entries[12].activeFrame == 1) {
- entries[20].animateOnFrame = 4;
- entries[20].playOnce = false;
- playSFX(-3, 128);
- } else {
- entries[20].playOnce = true;
- }
- if (!_isEnglishDemo)
- playSFX(-9, 128);
- }
-
- if (clickingOn == OPTIONMENUHOTSPOT_TEXT) {
-
- if (entries[4].activeFrame == 0) {
- _showConversationText = false;
- entries[4].activeFrame = 4;
- } else if (entries[4].activeFrame == 4) {
- _showConversationText = true;
- setFont(true);
- entries[4].activeFrame = 8;
- } else if(entries[4].activeFrame == 8) {
- _showConversationText = true;
- setFont(false);
- entries[4].activeFrame = 0;
+ default:
+ break;
+ }
+ }
+ }
}
-
- if (!_isEnglishDemo)
- playSFX(-9, 128);
- }
-
- // don't allow change to video mode
- if (clickingOn == OPTIONMENUHOTSPOT_VIDEO_MODE) {
- playSoundWrong();
- }
-
- if (clickingOn == OPTIONMENUHOTSPOT_PLAY) {
- doExit = true;
- exitGame = false;
- if (!_isEnglishDemo)
- _audioManager->playSFX(10, 128, true);
- }
-
- if (clickingOn == OPTIONMENUHOTSPOT_QUIT) {
- doExit = true;
- exitGame = true;
- _shouldQuit = true;
- if (!_isEnglishDemo)
- _audioManager->playSFX(10, 128, true);
}
}
@@ -984,9 +1116,15 @@ bool ToonEngine::showOptions() {
restorePalette();
dirtyAllScreen();
+ for (int entryNr = 0; entryNr < optionMenuEntryCount; ++entryNr)
+ delete entries[entryNr].animation;
delete[] entries;
+
delete optionPicture;
+ if (!_shouldQuit && exitGame) {
+ _shouldQuit = exitGame;
+ }
return exitGame;
}
@@ -998,47 +1136,57 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
MenuEntry entries[MAINMENU_ENTRYCOUNT];
- for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; entryNr++) {
+ for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; ++entryNr) {
entries[entryNr].menuMask = mainMenuFiles[entryNr].menuMask;
entries[entryNr].id = mainMenuFiles[entryNr].id;
entries[entryNr].animation = new Animation(this);
entries[entryNr].animation->loadAnimation(mainMenuFiles[entryNr].animationFile);
- if (entries[entryNr].id != MAINMENUHOTSPOT_NONE)
+ if (entries[entryNr].id != MAINMENUHOTSPOT_NONE) {
entries[entryNr].rect = entries[entryNr].animation->getRect();
+ if (entries[entryNr].id == MAINMENUHOTSPOT_HOTKEYSCLOSE) {
+ // In the original game, clicking anywhere on the
+ // hotspots' screen will return the user to the main menu
+ entries[entryNr].rect.top = 0;
+ entries[entryNr].rect.left = 0;
+ entries[entryNr].rect.right = TOON_SCREEN_WIDTH;
+ entries[entryNr].rect.bottom = TOON_SCREEN_HEIGHT;
+ }
+ }
entries[entryNr].animateOnFrame = mainMenuFiles[entryNr].animateOnFrame;
entries[entryNr].animateCurFrame = 0;
entries[entryNr].activeFrame = 0;
+ entries[entryNr].handled = false;
}
setCursor(0);
- bool doExit = false;
+ bool doExitMenu = false;
bool exitGame = false;
int menuMask = MAINMENUMASK_BASE;
Common::SeekableReadStream *mainmenuMusicFile = NULL;
AudioStreamInstance *mainmenuMusic = NULL;
bool musicPlaying = false;
+ int32 oldMouseButton = _mouseButton;
_gameState->_inMenu = true;
dirtyAllScreen();
- while (!doExit) {
+ while (!doExitMenu) {
int clickingOn = MAINMENUHOTSPOT_NONE;
- int clickRelease = false;
-
- if (!musicPlaying) {
- mainmenuMusicFile = resources()->openFile("BR091013.MUS");
- if (mainmenuMusicFile) {
- mainmenuMusic = new AudioStreamInstance(_audioManager, _mixer, mainmenuMusicFile, true);
- mainmenuMusic->play(false);
- musicPlaying = true;
- }
- else {
- musicPlaying = false;
- }
- }
+ int clickingOnSprite = 0;
+ bool clickRelease = false;
while (!clickRelease) {
+ if (!musicPlaying) {
+ mainmenuMusicFile = resources()->openFile("BR091013.MUS");
+ if (mainmenuMusicFile) {
+ mainmenuMusic = new AudioStreamInstance(_audioManager, _mixer, mainmenuMusicFile, true);
+ mainmenuMusic->play(false);
+ musicPlaying = true;
+ } else {
+ musicPlaying = false;
+ }
+ }
if (_dirtyAll) {
mainmenuPicture->draw(*_mainSurface, 0, 0, 0, 0);
@@ -1049,21 +1197,19 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
clearDirtyRects();
- for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; entryNr++) {
+ // Handle animations
+ for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; ++entryNr) {
if (entries[entryNr].menuMask & menuMask) {
if (entries[entryNr].animateOnFrame) {
- entries[entryNr].animateCurFrame++;
+ ++entries[entryNr].animateCurFrame;
if (entries[entryNr].animateOnFrame <= entries[entryNr].animateCurFrame) {
- entries[entryNr].activeFrame++;
+ ++entries[entryNr].activeFrame;
if (entries[entryNr].activeFrame >= entries[entryNr].animation->_numFrames)
entries[entryNr].activeFrame = 0;
entries[entryNr].animateCurFrame = 0;
}
}
- int32 frameNr = entries[entryNr].activeFrame;
- if ((entries[entryNr].id == clickingOn) && (clickingOn != MAINMENUHOTSPOT_NONE))
- frameNr = 1;
- entries[entryNr].animation->drawFrame(*_mainSurface, frameNr, 0, 0);
+ entries[entryNr].animation->drawFrame(*_mainSurface, entries[entryNr].activeFrame, 0, 0);
}
}
@@ -1072,95 +1218,169 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
_needPaletteFlush = false;
}
+ oldMouseButton = _mouseButton;
+
parseInput();
- copyToVirtualScreen(true);
- _system->delayMillis(17);
- if (_mouseButton & 1) {
- // left mouse button pushed down
+ if (_shouldQuit || doExitMenu) {
clickingOn = MAINMENUHOTSPOT_NONE;
- for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; entryNr++) {
- if (entries[entryNr].menuMask & menuMask) {
- if (entries[entryNr].id != MAINMENUHOTSPOT_NONE) {
- if (entries[entryNr].rect.contains(_mouseX, _mouseY))
- clickingOn = entries[entryNr].id;
+ clickRelease = true;
+ doExitMenu = true;
+ } else {
+ copyToVirtualScreen(true);
+ _system->delayMillis(17);
+
+ if (_mouseButton & 1) {
+ // left mouse button pushed down
+ for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; ++entryNr) {
+ if (entries[entryNr].menuMask & menuMask
+ && entries[entryNr].id != MAINMENUHOTSPOT_NONE
+ && entries[entryNr].rect.contains(_mouseX, _mouseY)
+ && (clickingOn == MAINMENUHOTSPOT_NONE && !(oldMouseButton & 1))) {
+ clickingOn = entries[entryNr].id;
+ clickingOnSprite = entryNr;
+ break;
}
}
- }
- } else {
- // left mouse button released/not pushed down
- if (clickingOn != MAINMENUHOTSPOT_NONE)
+ } else if (clickingOn != MAINMENUHOTSPOT_NONE) {
+ // left mouse button released/not pushed down
clickRelease = true;
- }
- if (_shouldQuit) {
- clickingOn = MAINMENUHOTSPOT_NONE;
- clickRelease = true;
- doExit = true;
- }
- }
+ clickingOn = MAINMENUHOTSPOT_NONE;
+ entries[clickingOnSprite].handled = false;
+ }
- if (clickingOn != MAINMENUHOTSPOT_NONE) {
- _audioManager->playSFX(10, 128, true);
- }
+ // handle buttons
+ if (clickingOn != MAINMENUHOTSPOT_NONE && !entries[clickingOnSprite].handled) {
+ // NOTE "MAINMENUHOTSPOT_HOTKEYSCLOSE" does not have two frames
+ if (entries[clickingOnSprite].animation->_numFrames > 1 && entries[clickingOnSprite].activeFrame == 0) {
+ // First show the button as clicked
+ entries[clickingOnSprite].activeFrame = 1;
+
+ // Use click sfx sound only for:
+ // Start game, Load Game and Hotkeys menu (but not going back from it)
+ // Use special sfx sound for quit
+ switch (clickingOn) {
+ case MAINMENUHOTSPOT_HOTKEYS:
+ // fall through
+ case MAINMENUHOTSPOT_START:
+ // fall through
+ case MAINMENUHOTSPOT_LOADGAME:
+ // fall through
+ playSFX(-9, 128);
+ break;
+
+ case MAINMENUHOTSPOT_QUIT:
+ playSFX(-8, 128);
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ entries[clickingOnSprite].handled = true;
+ switch (entries[clickingOnSprite].id) {
+ case MAINMENUHOTSPOT_HOTKEYS:
+ // fall through
+ case MAINMENUHOTSPOT_HOTKEYSCLOSE:
+ menuMask = clickingOn == MAINMENUHOTSPOT_HOTKEYS? MAINMENUMASK_HOTKEYS : MAINMENUMASK_BASE;
+ entries[clickingOnSprite].activeFrame = 0;
+ break;
+
+ case MAINMENUHOTSPOT_START:
+ // Start game (actually exit main menu)
+ clickingOn = MAINMENUHOTSPOT_NONE;
+ clickRelease = true;
+ loadedGame = false;
+ doExitMenu = true;
+ break;
+
+ case MAINMENUHOTSPOT_LOADGAME:
+ doExitMenu = loadGame(-1);
+ loadedGame = doExitMenu;
+ if (loadedGame) {
+ clickingOn = MAINMENUHOTSPOT_NONE;
+ clickRelease = true;
+ } else {
+ entries[clickingOnSprite].activeFrame = 0;
+ }
+ exitGame = false;
+ break;
+
+ case MAINMENUHOTSPOT_INTRO:
+ // fall through
+ case MAINMENUHOTSPOT_CREDITS:
+ if (musicPlaying) {
+ //stop music
+ mainmenuMusic->stop(false);
+ delete mainmenuMusicFile;
+ musicPlaying = false;
+ }
+ if (clickingOn == MAINMENUHOTSPOT_INTRO) {
+ // Play intro movies
+ getMoviePlayer()->play("209_1M.SMK", 0x10);
+ getMoviePlayer()->play("209_2M.SMK", 0x10);
+ getMoviePlayer()->play("209_3M.SMK", 0x10);
+ } else {
+ // Play credits movie
+ getMoviePlayer()->play("CREDITS.SMK", 0x0);
+ }
+ entries[clickingOnSprite].activeFrame = 0;
+ break;
+
+ case MAINMENUHOTSPOT_QUIT:
+ exitGame = showQuitConfirmationDialogue();
+ if (exitGame) {
+ clickingOn = MAINMENUHOTSPOT_NONE;
+ clickRelease = true;
+ doExitMenu = true;
+ } else {
+ entries[clickingOnSprite].activeFrame = 0;
+ }
+ break;
- switch (clickingOn) {
- case MAINMENUHOTSPOT_HOTKEYS:
- menuMask = MAINMENUMASK_HOTKEYS;
- continue;
- case MAINMENUHOTSPOT_HOTKEYSCLOSE:
- menuMask = MAINMENUMASK_BASE;
- continue;
- default:
- break;
+ default:
+ break;
+ }
+ }
+ }
+ }
}
- if (musicPlaying) {
+ if (musicPlaying && doExitMenu) {
//stop music
mainmenuMusic->stop(false);
delete mainmenuMusicFile;
musicPlaying = false;
}
-
- switch (clickingOn) {
- case MAINMENUHOTSPOT_START:
- // Start game (actually exit main menu)
- loadedGame = false;
- doExit = true;
- break;
- case MAINMENUHOTSPOT_INTRO:
- // Play intro movies
- getMoviePlayer()->play("209_1M.SMK", 0x10);
- getMoviePlayer()->play("209_2M.SMK", 0x10);
- getMoviePlayer()->play("209_3M.SMK", 0x10);
- break;
- case MAINMENUHOTSPOT_LOADGAME:
- doExit = loadGame(-1);
- loadedGame = doExit;
- exitGame = false;
- break;
- case MAINMENUHOTSPOT_CREDITS:
- // Play credits movie
- getMoviePlayer()->play("CREDITS.SMK", 0x0);
- break;
- case MAINMENUHOTSPOT_QUIT:
- exitGame = true;
- doExit = true;
- break;
- default:
- break;
- }
}
_gameState->_inMenu = false;
- //delete mainmenuMusic;
- for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; entryNr++)
+ for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; ++entryNr)
delete entries[entryNr].animation;
delete mainmenuPicture;
+ if (!_shouldQuit && exitGame) {
+ _shouldQuit = exitGame;
+ }
return !exitGame;
}
+bool ToonEngine::showQuitConfirmationDialogue() {
+ // In the original game this dialogue prompt was:
+ // "Are you sure you want to exit? (Y/N)"
+ // See: devtools\create_toon\staticdata.h
+ // We could allow create_toon to include this text
+ // and all its variations for the game's localizations in toon.dat,
+ // especially if we implement a native game dialogue prompt.
+ // But using ScummVM's Message Dialogue works just as well,
+ // and it requires a mouse click for yes/no selection
+ // instead of a keyboard key-press (which would also be dependent on the
+ // text variant of the yes/no option).
+ GUI::MessageDialog dialog(_("Are you sure you want to exit?"), _("Yes"), _("No"));
+ return (dialog.runModal() == GUI::kMessageOK);
+}
+
Common::Error ToonEngine::run() {
if (!loadToonDat())
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index bce3dfc2348..116605d7078 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -111,6 +111,7 @@ public:
Common::Error run() override;
bool showMainmenu(bool &loadedGame);
bool showOptions();
+ bool showQuitConfirmationDialogue();
void init();
bool loadToonDat();
char **loadTextsVariants(Common::File &in);
Commit: d3ded0e6eccc7a7e609f1f3d7ec41077681de70e
https://github.com/scummvm/scummvm/commit/d3ded0e6eccc7a7e609f1f3d7ec41077681de70e
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-06-12T15:15:55+02:00
Commit Message:
TOON: Handle hotkeys and related animations in menus
Changed paths:
engines/toon/toon.cpp
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 7784e5e3acf..2802b59b5dc 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -184,11 +184,15 @@ void ToonEngine::parseInput() {
_audioManager->stopCurrentVoice();
}
if (event.kbd.keycode == Common::KEYCODE_F5 && !hasModifier) {
- if (canSaveGameStateCurrently())
+ if (_gameState->_inMenu) {
+ playSoundWrong();
+ } else if (canSaveGameStateCurrently())
saveGame(-1, "");
}
if (event.kbd.keycode == Common::KEYCODE_F6 && !hasModifier) {
- if (canLoadGameStateCurrently())
+ if (_gameState->_inMenu) {
+ playSoundWrong();
+ } else if (canLoadGameStateCurrently())
loadGame(-1);
}
if (event.kbd.keycode == Common::KEYCODE_t && !hasModifier) {
@@ -203,8 +207,11 @@ void ToonEngine::parseInput() {
if (event.kbd.keycode == Common::KEYCODE_s && !hasModifier) {
_audioManager->muteSfx(!_audioManager->isSfxMuted());
}
- if (event.kbd.keycode == Common::KEYCODE_F1 && !hasModifier && !_gameState->_inMenu) {
- showOptions();
+ if (event.kbd.keycode == Common::KEYCODE_F1 && !hasModifier) {
+ if (_gameState->_inMenu) {
+ playSoundWrong();
+ } else
+ showOptions();
}
if (event.kbd.flags & Common::KBD_ALT) {
@@ -743,12 +750,16 @@ bool ToonEngine::showOptions() {
entries[2].activeFrame = entries[2].animation->_numFrames - 1;
+ const int textOffFrame = _isEnglishDemo ? 0 : 4;
+ const int textOnFrameFont1 = _isEnglishDemo ? 8 : 0;
+ const int textOnFrameFont2 = 8;
+
if (!_showConversationText) {
- entries[4].activeFrame = 4;
+ entries[4].activeFrame = textOffFrame;
} else if (_useAlternativeFont) {
- entries[4].activeFrame = 8;
+ entries[4].activeFrame = textOnFrameFont2;
} else {
- entries[4].activeFrame = 0;
+ entries[4].activeFrame = textOnFrameFont1;
}
// Variables for the English demo sparkle animation.
@@ -764,6 +775,7 @@ bool ToonEngine::showOptions() {
bool doExitMenu = false;
bool exitGame = false;
bool targetFrameExceeded = false;
+
_gameState->_inMenu = true;
dirtyAllScreen();
_firstFrame = true;
@@ -886,7 +898,7 @@ bool ToonEngine::showOptions() {
oldMouseY = _mouseY;
oldMouseButton = _mouseButton;
- // update mouse clicking state
+ // update mouse clicking state and handle hotkeys
parseInput();
// NOTE Placing the code here seems to mitigate the issue
@@ -905,6 +917,69 @@ bool ToonEngine::showOptions() {
}
_system->delayMillis(17);
+ // animations related with handling hotkey commands
+ if (entries[4].animateOnFrame == 0) {
+ if (!_showConversationText && entries[4].activeFrame != textOffFrame) {
+ entries[4].targetFrame = textOffFrame;
+ entries[4].animateOnFrame = 1;
+ entries[4].playOnce = true;
+ } else if (_showConversationText
+ && (entries[4].activeFrame != textOnFrameFont1
+ && (_isEnglishDemo || (!_isEnglishDemo && entries[4].activeFrame != textOnFrameFont2)))) {
+ entries[4].targetFrame = textOnFrameFont1;
+ entries[4].animateOnFrame = 1;
+ entries[4].playOnce = true;
+ }
+ if (!_isEnglishDemo && entries[4].animateOnFrame == 1) {
+ playSFX(-9, 128);
+ }
+ }
+
+ if (entries[9].animateOnFrame == 0) {
+ if (!_audioManager->isMusicMuted() && entries[9].activeFrame != entries[9].animation->_numFrames - 1) {
+ entries[9].targetFrame = entries[9].animation->_numFrames - 1;
+ entries[9].animateOnFrame = 1;
+ entries[9].playOnce = true;
+ } else if (_audioManager->isMusicMuted() && entries[9].activeFrame != 0) {
+ entries[9].targetFrame = 0;
+ entries[9].animateOnFrame = 1;
+ entries[9].playOnce = true;
+ }
+ if (!_isEnglishDemo && entries[9].animateOnFrame == 1) {
+ playSFX(-7, 128);
+ }
+ }
+
+ if (entries[7].animateOnFrame == 0) {
+ if (!_audioManager->isVoiceMuted() && entries[7].activeFrame != entries[7].animation->_numFrames - 1) {
+ entries[7].targetFrame = entries[7].animation->_numFrames - 1;
+ entries[7].animateOnFrame = 1;
+ entries[7].playOnce = true;
+ } else if (_audioManager->isVoiceMuted() && entries[7].activeFrame != 0) {
+ entries[7].targetFrame = 0;
+ entries[7].animateOnFrame = 1;
+ entries[7].playOnce = true;
+ }
+ if (!_isEnglishDemo && entries[7].animateOnFrame == 1) {
+ playSFX(-7, 128);
+ }
+ }
+
+ if (entries[5].animateOnFrame == 0) {
+ if (!_audioManager->isSfxMuted() && entries[5].activeFrame != entries[5].animation->_numFrames - 1) {
+ entries[5].targetFrame = entries[5].animation->_numFrames - 1;
+ entries[5].animateOnFrame = 1;
+ entries[5].playOnce = true;
+ } else if (_audioManager->isSfxMuted() && entries[5].activeFrame != 0) {
+ entries[5].targetFrame = 0;
+ entries[5].animateOnFrame = 1;
+ entries[5].playOnce = true;
+ }
+ if (!_isEnglishDemo && entries[5].animateOnFrame == 1) {
+ playSFX(-7, 128);
+ }
+ }
+
// Avoid unnecessary checks and actions if mouse has not moved or changed status
if (oldMouseButton != _mouseButton
|| ((_mouseButton & 1)
@@ -992,7 +1067,7 @@ bool ToonEngine::showOptions() {
// fall through
case OPTIONMENUHOTSPOT_VOLUMESFX:
entries[clickingOnSprite].handled = true;
- if (entries[clickingOnSprite].activeFrame == 0) {
+ if (entries[clickingOnSprite].activeFrame != entries[clickingOnSprite].animation->_numFrames - 1) {
entries[clickingOnSprite].targetFrame = entries[clickingOnSprite].animation->_numFrames - 1;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
@@ -1066,7 +1141,8 @@ bool ToonEngine::showOptions() {
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
}
- playSFX(-9, 128);
+ if (entries[clickingOnSprite].animateOnFrame == 1)
+ playSFX(-9, 128);
} else {
// In the demo, the behavior is different:
// Clicking anywhere in the Text Dial hotspot
Commit: cc89609e079378d8b77d8107fcc9a2a077343877
https://github.com/scummvm/scummvm/commit/cc89609e079378d8b77d8107fcc9a2a077343877
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-06-12T15:15:55+02:00
Commit Message:
TOON: Do not allow disable speech and subtitles at the same time
The original deals with this by activating the subtitles (Font 1) when deactivating speech
The original also has the bug whereby on some edge cases (eg using the hotkeys to mute dialogue and disable text while in-game) both text and speech get disabled, which results in behavior like the actors are stuck doing nothing when examing an item or such. We fix this bug here.
Changed paths:
engines/toon/toon.cpp
engines/toon/toon.h
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 2802b59b5dc..a9fee6f5e42 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -196,13 +196,23 @@ void ToonEngine::parseInput() {
loadGame(-1);
}
if (event.kbd.keycode == Common::KEYCODE_t && !hasModifier) {
- _showConversationText = !_showConversationText;
+ if (_showConversationText) {
+ turnOnText(false);
+ if (_audioManager->isVoiceMuted()) {
+ turnOnText(true, false);
+ }
+ } else {
+ turnOnText(true, false);
+ }
}
if (event.kbd.keycode == Common::KEYCODE_m && !hasModifier) {
_audioManager->muteMusic(!_audioManager->isMusicMuted());
}
if (event.kbd.keycode == Common::KEYCODE_d && !hasModifier) {
_audioManager->muteVoice(!_audioManager->isVoiceMuted());
+ if (!_showConversationText && _audioManager->isVoiceMuted()) {
+ turnOnText(true, false);
+ }
}
if (event.kbd.keycode == Common::KEYCODE_s && !hasModifier) {
_audioManager->muteSfx(!_audioManager->isSfxMuted());
@@ -980,6 +990,22 @@ bool ToonEngine::showOptions() {
}
}
+
+ // This visualizes that the text dial cannot be set to Text Off,
+ // if the voice is also muted or voice volume is set to 0.
+ if (!_showConversationText
+ && (_audioManager->isVoiceMuted() || _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) == 0)
+ && (entries[4].activeFrame != textOnFrameFont1
+ && (_isEnglishDemo || (!_isEnglishDemo && entries[4].activeFrame != textOnFrameFont2)))
+ && entries[4].animateOnFrame == 0) {
+ entries[4].targetFrame = textOnFrameFont1;
+ entries[4].animateOnFrame = 1;
+ entries[4].playOnce = true;
+ if (!_isEnglishDemo) {
+ playSFX(-9, 128);
+ }
+ }
+
// Avoid unnecessary checks and actions if mouse has not moved or changed status
if (oldMouseButton != _mouseButton
|| ((_mouseButton & 1)
@@ -1030,6 +1056,11 @@ bool ToonEngine::showOptions() {
else
chosenSoundType = Audio::Mixer::kSFXSoundType;
_mixer->setVolumeForSoundType(chosenSoundType, targetVol);
+
+ if (_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) == 0
+ && !_showConversationText) {
+ turnOnText(true, false);
+ }
break;
case OPTIONMENUHOTSPOT_TEXTSPEED:
@@ -1081,11 +1112,14 @@ bool ToonEngine::showOptions() {
entries[clickingOnSprite].targetFrame = 0;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
- if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSIC)
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSIC) {
_audioManager->muteMusic(true);
- else if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICE)
+ } else if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICE) {
_audioManager->muteVoice(true);
- else
+ if (!_showConversationText) {
+ turnOnText(true, false);
+ }
+ } else
_audioManager->muteSfx(true);
}
if (!_isEnglishDemo)
@@ -1124,19 +1158,21 @@ bool ToonEngine::showOptions() {
if (!_isEnglishDemo) {
if ((ratioY <= 151 && ratioX >= 88 && ratioX <= 169)
|| (ratioY > 151 && ratioX >= 122 && ratioX <= 145) ) {
- _showConversationText = false;
+ turnOnText(false);
+ if (_audioManager->isVoiceMuted()
+ || _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) == 0) {
+ turnOnText(true, false);
+ }
entries[clickingOnSprite].targetFrame = 4;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
} else if (ratioY > 151 && ratioX > 145) {
- _showConversationText = true;
- setFont(true);
+ turnOnText(true, true);
entries[clickingOnSprite].targetFrame = 8;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
} else if (ratioY > 151 && ratioX < 122) {
- _showConversationText = true;
- setFont(false);
+ turnOnText(true, false);
entries[clickingOnSprite].targetFrame = 0;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
@@ -1149,14 +1185,18 @@ bool ToonEngine::showOptions() {
// toggles between "Text Off" and "Text On"
switch (entries[clickingOnSprite].activeFrame) {
case 0:
- _showConversationText = true;
+ turnOnText(true, false);
entries[clickingOnSprite].targetFrame = 8;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
break;
case 8:
- _showConversationText = false;
+ turnOnText(false);
+ if (_audioManager->isVoiceMuted()
+ || _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) == 0) {
+ turnOnText(true, false);
+ }
entries[clickingOnSprite].targetFrame = 0;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
@@ -2550,6 +2590,12 @@ void ToonEngine::setFont(bool alternative) {
_useAlternativeFont = alternative;
}
+void ToonEngine::turnOnText(bool enable, bool useAlternativeFont) {
+ _showConversationText = enable;
+ if (_showConversationText && !_isEnglishDemo)
+ setFont(useAlternativeFont);
+}
+
void ToonEngine::drawInfoLine() {
if (_currentHotspotItem != 0 && !_gameState->_mouseHidden && !_gameState->_inConversation) {
const char *infoTool = NULL;
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index 116605d7078..3a164aa69de 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -214,6 +214,7 @@ public:
bool canSaveGameStateCurrently() override;
bool canLoadGameStateCurrently() override;
void pauseEngineIntern(bool pause) override;
+ void turnOnText(bool enable, bool useAlternativeFont = false);
Resources *resources() {
return _resources;
Commit: 41d4d4df3dd420f0d891e43aae3b60375c1f2742
https://github.com/scummvm/scummvm/commit/41d4d4df3dd420f0d891e43aae3b60375c1f2742
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-06-12T15:15:55+02:00
Commit Message:
TOON: Store textSpeed value and fix sound volume slider needle
The fix is for keeping the volume needle indicator at the same position upon resuming the Options Menu
Changed paths:
engines/toon/toon.cpp
engines/toon/toon.h
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index a9fee6f5e42..79b82c0e5d4 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -751,12 +751,11 @@ bool ToonEngine::showOptions() {
entries[8].activeFrame = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) * (entries[8].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
entries[6].activeFrame = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) * (entries[6].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
- entries[9].activeFrame = _audioManager->isMusicMuted() ? 0 : 3;
- entries[7].activeFrame = _audioManager->isVoiceMuted() ? 0 : 3;
- entries[5].activeFrame = _audioManager->isSfxMuted() ? 0 : 3;
+ entries[9].activeFrame = _audioManager->isMusicMuted() ? 0 : entries[9].animation->_numFrames - 1;
+ entries[7].activeFrame = _audioManager->isVoiceMuted() ? 0 : entries[7].animation->_numFrames - 1;
+ entries[5].activeFrame = _audioManager->isSfxMuted() ? 0 : entries[5].animation->_numFrames - 1;
- // TODO retrieve stored textSpeed value and set the needle indicator accordingly
- entries[3].activeFrame = 0;
+ entries[3].activeFrame = _textSpeed * (entries[3].animation->_numFrames - 1) / 255;
entries[2].activeFrame = entries[2].animation->_numFrames - 1;
@@ -1049,12 +1048,18 @@ bool ToonEngine::showOptions() {
entries[clickingOnSprite].playOnce = true;
targetVol = entries[clickingOnSprite].targetFrame * Audio::Mixer::kMaxMixerVolume / (entries[clickingOnSprite].animation->_numFrames - 1);
- if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER)
+ // Since we use integer division, find a value for targetVol that will produce the same targetFrame we have calculated
+ // We need this value for setting the proper frame for the slider needle indicator, when resuming the Options menu.
+ while (entries[clickingOnSprite].targetFrame > targetVol * (entries[clickingOnSprite].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume)
+ ++targetVol;
+
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER) {
chosenSoundType = Audio::Mixer::kMusicSoundType;
- else if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER)
+ } else if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER) {
chosenSoundType = Audio::Mixer::kSpeechSoundType;
- else
+ } else {
chosenSoundType = Audio::Mixer::kSFXSoundType;
+ }
_mixer->setVolumeForSoundType(chosenSoundType, targetVol);
if (_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) == 0
@@ -1067,6 +1072,12 @@ bool ToonEngine::showOptions() {
entries[clickingOnSprite].targetFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
+
+ _textSpeed = entries[clickingOnSprite].targetFrame * 255 / (entries[clickingOnSprite].animation->_numFrames - 1);
+ // Since we use integer division, find a value for _textSpeed that will produce the same targetFrame we have calculated
+ // We need this value for setting the proper frame for the slider needle indicator, when resuming the Options menu.
+ while (entries[clickingOnSprite].targetFrame > _textSpeed * (entries[clickingOnSprite].animation->_numFrames - 1) / 255)
+ ++_textSpeed;
// TODO store textSpeed
break;
@@ -1544,6 +1555,7 @@ ToonEngine::ToonEngine(OSystem *syst, const ADGameDescription *gameDescription)
_inventoryPicture = NULL;
_currentMask = NULL;
_showConversationText = true;
+ _textSpeed = 60;
_useAlternativeFont = false;
_isDemo = _gameDescription->flags & ADGF_DEMO;
_isEnglishDemo = _isDemo && _gameDescription->language == Common::EN_ANY;
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index 3a164aa69de..9269826fcff 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -441,6 +441,7 @@ protected:
bool _isDemo;
bool _isEnglishDemo;
bool _showConversationText;
+ int _textSpeed;
bool _useAlternativeFont;
bool _needPaletteFlush;
};
Commit: e8791aba9e580b2c8c48c45e0a4bcb560d80b6f0
https://github.com/scummvm/scummvm/commit/e8791aba9e580b2c8c48c45e0a4bcb560d80b6f0
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-06-12T15:15:55+02:00
Commit Message:
TOON: Mute music now works in intro main menu
Pressing hotkey M now mutes the music as it should
Changed paths:
engines/toon/audio.cpp
engines/toon/audio.h
engines/toon/toon.cpp
diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp
index e3d9c0de36c..31d44a668a2 100644
--- a/engines/toon/audio.cpp
+++ b/engines/toon/audio.cpp
@@ -83,20 +83,25 @@ void AudioManager::removeInstance(AudioStreamInstance *inst) {
}
}
-void AudioManager::playMusic(const Common::String &dir, const Common::String &music) {
+int AudioManager::playMusic(const Common::String &dir, const Common::String &music) {
debugC(1, kDebugAudio, "playMusic(%s, %s)", dir.c_str(), music.c_str());
// two musics can be played at same time
- Common::String path = Common::String::format("ACT%d/%s/%s.MUS", _vm->state()->_currentChapter, dir.c_str(), music.c_str());
+ Common::String path;
+ if (dir == "") {
+ path = Common::String::format("%s.MUS", music.c_str());
+ } else {
+ path = Common::String::format("ACT%d/%s/%s.MUS", _vm->state()->_currentChapter, dir.c_str(), music.c_str());
+ }
if (_currentMusicName == music)
- return;
+ return -1;
_currentMusicName = music;
Common::SeekableReadStream *srs = _vm->resources()->openFile(path);
if (!srs)
- return;
+ return -1;
// see what channel to take
// if the current channel didn't really start. reuse this one
@@ -118,10 +123,11 @@ void AudioManager::playMusic(const Common::String &dir, const Common::String &mu
_channels[_currentMusicChannel]->stop(false);
}
- // no need to delete instance here it will automatically deleted by the mixer is done with it
+ // no need to delete instance here; it will automatically be deleted by the mixer when it is done with it
_channels[_currentMusicChannel] = new AudioStreamInstance(this, _mixer, srs, true, true);
_channels[_currentMusicChannel]->setVolume(_musicMuted ? 0 : 255);
_channels[_currentMusicChannel]->play(true, Audio::Mixer::kMusicSoundType);
+ return _currentMusicChannel;
}
bool AudioManager::voiceStillPlaying() {
@@ -215,13 +221,20 @@ void AudioManager::setMusicVolume(int32 volume) {
_channels[1]->setVolume(volume);
}
-void AudioManager::stopMusic() {
+void AudioManager::stopMusicChannel(int channelId, bool fade) {
+ if (_channels[channelId])
+ _channels[channelId]->stop(fade);
+
+ if (_currentMusicChannel == channelId)
+ // clean _currentMusicName too
+ _currentMusicName = "";
+}
+
+void AudioManager::stopMusic(bool fade) {
debugC(1, kDebugAudio, "stopMusic()");
- if (_channels[0])
- _channels[0]->stop(true);
- if (_channels[1])
- _channels[1]->stop(true);
+ stopMusicChannel(0, fade);
+ stopMusicChannel(1, fade);
}
AudioStreamInstance::AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer, Common::SeekableReadStream *stream , bool looping, bool deleteFileStreamAtEnd) {
diff --git a/engines/toon/audio.h b/engines/toon/audio.h
index ff1a0885622..b254182e1fe 100644
--- a/engines/toon/audio.h
+++ b/engines/toon/audio.h
@@ -130,13 +130,14 @@ public:
bool voiceStillPlaying();
- void playMusic(const Common::String &dir, const Common::String &music);
+ int playMusic(const Common::String &dir, const Common::String &music);
void playVoice(int32 id, bool genericVoice);
int32 playSFX(int32 id, int volume, bool genericSFX);
void stopCurrentVoice();
void stopAllSfxs();
void setMusicVolume(int32 volume);
- void stopMusic();
+ void stopMusicChannel(int channelId, bool fade);
+ void stopMusic(bool fade = true);
void muteVoice(bool mute);
void muteMusic(bool mute);
void muteSfx(bool mute);
@@ -154,14 +155,15 @@ public:
bool loadAudioPack(int32 id, const Common::String &indexFile, const Common::String &packFile);
AudioStreamInstance *_channels[16]; // 0-1 : music
- // 2 : voice
- // 3-16 : SFX
+ // 2 : voice
+ // 3-16 : SFX
AudioStreamPackage *_audioPacks[4]; // 0 : generic streams
- // 1 : local streams
- // 2 : generic SFX
- // 3 : local SFX
- uint32 _currentMusicChannel;
+ // 1 : local streams
+ // 2 : generic SFX
+ // 3 : local SFX
+
+ int _currentMusicChannel;
Common::String _currentMusicName;
ToonEngine *_vm;
Audio::Mixer *_mixer;
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 79b82c0e5d4..8150f58e1ab 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -1290,9 +1290,8 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
bool doExitMenu = false;
bool exitGame = false;
int menuMask = MAINMENUMASK_BASE;
- Common::SeekableReadStream *mainmenuMusicFile = NULL;
- AudioStreamInstance *mainmenuMusic = NULL;
bool musicPlaying = false;
+ int musicPlayingChannel = -1;
int32 oldMouseButton = _mouseButton;
_gameState->_inMenu = true;
@@ -1305,14 +1304,8 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
while (!clickRelease) {
if (!musicPlaying) {
- mainmenuMusicFile = resources()->openFile("BR091013.MUS");
- if (mainmenuMusicFile) {
- mainmenuMusic = new AudioStreamInstance(_audioManager, _mixer, mainmenuMusicFile, true);
- mainmenuMusic->play(false);
- musicPlaying = true;
- } else {
- musicPlaying = false;
- }
+ musicPlayingChannel = _audioManager->playMusic("", "BR091013");
+ musicPlaying = musicPlayingChannel >= 0;
}
if (_dirtyAll) {
@@ -1422,6 +1415,7 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
break;
case MAINMENUHOTSPOT_LOADGAME:
+
doExitMenu = loadGame(-1);
loadedGame = doExitMenu;
if (loadedGame) {
@@ -1438,8 +1432,7 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
case MAINMENUHOTSPOT_CREDITS:
if (musicPlaying) {
//stop music
- mainmenuMusic->stop(false);
- delete mainmenuMusicFile;
+ _audioManager->stopMusicChannel(musicPlayingChannel, false);
musicPlaying = false;
}
if (clickingOn == MAINMENUHOTSPOT_INTRO) {
@@ -1475,8 +1468,7 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
if (musicPlaying && doExitMenu) {
//stop music
- mainmenuMusic->stop(false);
- delete mainmenuMusicFile;
+ _audioManager->stopMusicChannel(musicPlayingChannel, false);
musicPlaying = false;
}
}
Commit: 6e444fe3ff4f870eb179261778c983a05f51c16a
https://github.com/scummvm/scummvm/commit/6e444fe3ff4f870eb179261778c983a05f51c16a
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-06-12T15:15:55+02:00
Commit Message:
TOON: Adjust movie volume to max of other sound type volumes
The original game seems to do something similar to this
Changed paths:
engines/toon/toon.cpp
engines/toon/toon.h
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 8150f58e1ab..42ed9d92889 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -152,6 +152,8 @@ void ToonEngine::init() {
_audioManager->loadAudioPack(0, "GENERIC.SVI", "GENERIC.SVL");
_audioManager->loadAudioPack(2, "GENERIC.SEI", "GENERIC.SEL");
+ adjustMovieVolume();
+
_lastMouseButton = 0;
_mouseButton = 0;
_lastRenderTime = _system->getMillis();
@@ -207,15 +209,18 @@ void ToonEngine::parseInput() {
}
if (event.kbd.keycode == Common::KEYCODE_m && !hasModifier) {
_audioManager->muteMusic(!_audioManager->isMusicMuted());
+ adjustMovieVolume();
}
if (event.kbd.keycode == Common::KEYCODE_d && !hasModifier) {
_audioManager->muteVoice(!_audioManager->isVoiceMuted());
+ adjustMovieVolume();
if (!_showConversationText && _audioManager->isVoiceMuted()) {
turnOnText(true, false);
}
}
if (event.kbd.keycode == Common::KEYCODE_s && !hasModifier) {
_audioManager->muteSfx(!_audioManager->isSfxMuted());
+ adjustMovieVolume();
}
if (event.kbd.keycode == Common::KEYCODE_F1 && !hasModifier) {
if (_gameState->_inMenu) {
@@ -1061,6 +1066,7 @@ bool ToonEngine::showOptions() {
chosenSoundType = Audio::Mixer::kSFXSoundType;
}
_mixer->setVolumeForSoundType(chosenSoundType, targetVol);
+ adjustMovieVolume();
if (_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) == 0
&& !_showConversationText) {
@@ -1133,6 +1139,7 @@ bool ToonEngine::showOptions() {
} else
_audioManager->muteSfx(true);
}
+ adjustMovieVolume();
if (!_isEnglishDemo)
playSFX(-7, 128);
break;
@@ -1500,6 +1507,13 @@ bool ToonEngine::showQuitConfirmationDialogue() {
return (dialog.runModal() == GUI::kMessageOK);
}
+void ToonEngine::adjustMovieVolume() {
+ int movieVol = MAX<int>((_audioManager->isMusicMuted() ? 0 : _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType)),
+ (_audioManager->isVoiceMuted() ? 0 : _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType)));
+ movieVol = MAX<int>(movieVol,(_audioManager->isSfxMuted() ? 0 : _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType)));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, movieVol);
+}
+
Common::Error ToonEngine::run() {
if (!loadToonDat())
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index 9269826fcff..d4357a63922 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -112,6 +112,7 @@ public:
bool showMainmenu(bool &loadedGame);
bool showOptions();
bool showQuitConfirmationDialogue();
+ void adjustMovieVolume();
void init();
bool loadToonDat();
char **loadTextsVariants(Common::File &in);
Commit: 0a004da866944828940b07149dfffe2095f2aba4
https://github.com/scummvm/scummvm/commit/0a004da866944828940b07149dfffe2095f2aba4
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-06-12T15:15:55+02:00
Commit Message:
TOON: Fix comment mentioning up to 16 audio channel id
Changed paths:
engines/toon/audio.h
diff --git a/engines/toon/audio.h b/engines/toon/audio.h
index b254182e1fe..01876b6f6a8 100644
--- a/engines/toon/audio.h
+++ b/engines/toon/audio.h
@@ -156,7 +156,7 @@ public:
AudioStreamInstance *_channels[16]; // 0-1 : music
// 2 : voice
- // 3-16 : SFX
+ // 3-15 : SFX
AudioStreamPackage *_audioPacks[4]; // 0 : generic streams
// 1 : local streams
Commit: 2db6be103865225c5da2d5a8e4ad0457f5bc71fb
https://github.com/scummvm/scummvm/commit/2db6be103865225c5da2d5a8e4ad0457f5bc71fb
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-06-12T15:15:55+02:00
Commit Message:
TOON: Synch and persist game config with ConfMan properly
Changed paths:
engines/toon/audio.cpp
engines/toon/audio.h
engines/toon/toon.cpp
engines/toon/toon.h
diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp
index 31d44a668a2..0ed17241ddf 100644
--- a/engines/toon/audio.cpp
+++ b/engines/toon/audio.cpp
@@ -127,6 +127,7 @@ int AudioManager::playMusic(const Common::String &dir, const Common::String &mus
_channels[_currentMusicChannel] = new AudioStreamInstance(this, _mixer, srs, true, true);
_channels[_currentMusicChannel]->setVolume(_musicMuted ? 0 : 255);
_channels[_currentMusicChannel]->play(true, Audio::Mixer::kMusicSoundType);
+
return _currentMusicChannel;
}
@@ -212,7 +213,7 @@ bool AudioManager::loadAudioPack(int32 id, const Common::String &indexFile, cons
return _audioPacks[id]->loadAudioPackage(indexFile, packFile);
}
-void AudioManager::setMusicVolume(int32 volume) {
+void AudioManager::setMusicVolume(uint8 volume) {
debugC(1, kDebugAudio, "setMusicVolume(%d)", volume);
if (_channels[0])
_channels[0]->setVolume(volume);
diff --git a/engines/toon/audio.h b/engines/toon/audio.h
index 01876b6f6a8..bb7c7ae58c6 100644
--- a/engines/toon/audio.h
+++ b/engines/toon/audio.h
@@ -135,15 +135,15 @@ public:
int32 playSFX(int32 id, int volume, bool genericSFX);
void stopCurrentVoice();
void stopAllSfxs();
- void setMusicVolume(int32 volume);
+ void setMusicVolume(uint8 volume);
void stopMusicChannel(int channelId, bool fade);
void stopMusic(bool fade = true);
void muteVoice(bool mute);
void muteMusic(bool mute);
void muteSfx(bool mute);
- bool isVoiceMuted() { return _voiceMuted; }
- bool isMusicMuted() { return _musicMuted; }
- bool isSfxMuted() { return _sfxMuted; }
+ bool isVoiceMuted() const { return _voiceMuted; }
+ bool isMusicMuted() const { return _musicMuted; }
+ bool isSfxMuted() const { return _sfxMuted; }
void startAmbientSFX(int32 id, int32 delay, int32 mode, int32 volume);
void killAmbientSFX(int32 id);
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 42ed9d92889..3145c68a7cc 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -28,6 +28,7 @@
#include "common/memstream.h"
#include "common/translation.h"
+#include "audio/mididrv.h"
#include "engines/advancedDetector.h"
#include "engines/util.h"
#include "graphics/palette.h"
@@ -47,6 +48,20 @@
namespace Toon {
void ToonEngine::init() {
+ // Assign default values to the ScummVM configuration manager, in case settings are missing
+ ConfMan.registerDefault("music_volume", 192);
+ ConfMan.registerDefault("speech_volume", 192);
+ ConfMan.registerDefault("sfx_volume", 192);
+ ConfMan.registerDefault("music_mute", "false");
+ ConfMan.registerDefault("speech_mute", "false");
+ ConfMan.registerDefault("sfx_mute", "false");
+ ConfMan.registerDefault("mute", "false");
+ ConfMan.registerDefault("subtitles", "true");
+ ConfMan.registerDefault("talkspeed", 60); // Can go up to 255
+ if (!_isEnglishDemo) {
+ ConfMan.registerDefault("alternative_font", "false");
+ }
+
_currentScriptRegion = 0;
_resources = new Resources(this);
_animationManager = new AnimationManager(this);
@@ -88,8 +103,6 @@ void ToonEngine::init() {
SearchMan.addSubDirectoryMatching(gameDataDir, "ACT1");
SearchMan.addSubDirectoryMatching(gameDataDir, "ACT2");
- syncSoundSettings();
-
_pathFinding = new PathFinding();
resources()->openPackage("LOCAL.PAK");
@@ -107,8 +120,6 @@ void ToonEngine::init() {
_drew = _characters[0];
_flux = _characters[1];
-
-
// preload walk anim for flux and drew
_drew->loadWalkAnimation("STNDWALK.CAF");
_drew->setupPalette();
@@ -152,7 +163,12 @@ void ToonEngine::init() {
_audioManager->loadAudioPack(0, "GENERIC.SVI", "GENERIC.SVL");
_audioManager->loadAudioPack(2, "GENERIC.SEI", "GENERIC.SEL");
- adjustMovieVolume();
+
+ // Query the selected music device (defaults to MT_AUTO device).
+ MidiDriver::DeviceHandle dev = MidiDriver::getDeviceHandle(ConfMan.hasKey("music_driver") ? ConfMan.get("music_driver") : Common::String("auto"));
+ _noMusicDriver = (MidiDriver::getMusicType(dev) == MT_NULL || MidiDriver::getMusicType(dev) == MT_INVALID);
+
+ syncSoundSettings();
_lastMouseButton = 0;
_mouseButton = 0;
@@ -198,29 +214,20 @@ void ToonEngine::parseInput() {
loadGame(-1);
}
if (event.kbd.keycode == Common::KEYCODE_t && !hasModifier) {
- if (_showConversationText) {
- turnOnText(false);
- if (_audioManager->isVoiceMuted()) {
- turnOnText(true, false);
- }
- } else {
- turnOnText(true, false);
- }
+ ConfMan.setBool("subtitles", !ConfMan.getBool("subtitles"));
+ syncSoundSettings();
}
if (event.kbd.keycode == Common::KEYCODE_m && !hasModifier) {
- _audioManager->muteMusic(!_audioManager->isMusicMuted());
- adjustMovieVolume();
+ ConfMan.setBool("music_mute", !ConfMan.getBool("music_mute"));
+ syncSoundSettings();
}
if (event.kbd.keycode == Common::KEYCODE_d && !hasModifier) {
- _audioManager->muteVoice(!_audioManager->isVoiceMuted());
- adjustMovieVolume();
- if (!_showConversationText && _audioManager->isVoiceMuted()) {
- turnOnText(true, false);
- }
+ ConfMan.setBool("speech_mute", !ConfMan.getBool("speech_mute"));
+ syncSoundSettings();
}
if (event.kbd.keycode == Common::KEYCODE_s && !hasModifier) {
- _audioManager->muteSfx(!_audioManager->isSfxMuted());
- adjustMovieVolume();
+ ConfMan.setBool("sfx_mute", !ConfMan.getBool("sfx_mute"));
+ syncSoundSettings();
}
if (event.kbd.keycode == Common::KEYCODE_F1 && !hasModifier) {
if (_gameState->_inMenu) {
@@ -611,7 +618,6 @@ enum OptionMenuMasks {
OPTIONMENUMASK_EVERYWHERE = 1
};
-
struct MenuFile {
int menuMask;
int id;
@@ -752,9 +758,9 @@ bool ToonEngine::showOptions() {
}
// Setting dial / option value in the game options menu
- entries[10].activeFrame = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) * (entries[10].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
- entries[8].activeFrame = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) * (entries[8].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
- entries[6].activeFrame = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) * (entries[6].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
+ entries[10].activeFrame = ConfMan.getInt("music_volume") * (entries[10].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
+ entries[8].activeFrame = ConfMan.getInt("speech_volume") * (entries[8].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
+ entries[6].activeFrame = ConfMan.getInt("sfx_volume") * (entries[6].animation->_numFrames - 1) / Audio::Mixer::kMaxMixerVolume;
entries[9].activeFrame = _audioManager->isMusicMuted() ? 0 : entries[9].animation->_numFrames - 1;
entries[7].activeFrame = _audioManager->isVoiceMuted() ? 0 : entries[7].animation->_numFrames - 1;
@@ -797,8 +803,8 @@ bool ToonEngine::showOptions() {
int32 oldMouseX = _mouseX;
int32 oldMouseY = _mouseY;
int32 oldMouseButton = _mouseButton;
- int targetVol;
- Audio::Mixer::SoundType chosenSoundType;
+ int targetVol, targetTextSpeed;
+ Common::String chosenConfVolumeSoundKey;
while (!doExitMenu) {
@@ -940,7 +946,10 @@ bool ToonEngine::showOptions() {
} else if (_showConversationText
&& (entries[4].activeFrame != textOnFrameFont1
&& (_isEnglishDemo || (!_isEnglishDemo && entries[4].activeFrame != textOnFrameFont2)))) {
- entries[4].targetFrame = textOnFrameFont1;
+ if (!_isEnglishDemo) {
+ entries[4].targetFrame = ConfMan.getBool("alternative_font") ? textOnFrameFont2 : textOnFrameFont1;
+ } else
+ entries[4].targetFrame = textOnFrameFont1;
entries[4].animateOnFrame = 1;
entries[4].playOnce = true;
}
@@ -994,22 +1003,6 @@ bool ToonEngine::showOptions() {
}
}
-
- // This visualizes that the text dial cannot be set to Text Off,
- // if the voice is also muted or voice volume is set to 0.
- if (!_showConversationText
- && (_audioManager->isVoiceMuted() || _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) == 0)
- && (entries[4].activeFrame != textOnFrameFont1
- && (_isEnglishDemo || (!_isEnglishDemo && entries[4].activeFrame != textOnFrameFont2)))
- && entries[4].animateOnFrame == 0) {
- entries[4].targetFrame = textOnFrameFont1;
- entries[4].animateOnFrame = 1;
- entries[4].playOnce = true;
- if (!_isEnglishDemo) {
- playSFX(-9, 128);
- }
- }
-
// Avoid unnecessary checks and actions if mouse has not moved or changed status
if (oldMouseButton != _mouseButton
|| ((_mouseButton & 1)
@@ -1059,18 +1052,15 @@ bool ToonEngine::showOptions() {
++targetVol;
if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER) {
- chosenSoundType = Audio::Mixer::kMusicSoundType;
+ chosenConfVolumeSoundKey = "music_volume";
} else if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER) {
- chosenSoundType = Audio::Mixer::kSpeechSoundType;
+ chosenConfVolumeSoundKey = "speech_volume";
} else {
- chosenSoundType = Audio::Mixer::kSFXSoundType;
+ chosenConfVolumeSoundKey = "sfx_volume";
}
- _mixer->setVolumeForSoundType(chosenSoundType, targetVol);
- adjustMovieVolume();
-
- if (_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) == 0
- && !_showConversationText) {
- turnOnText(true, false);
+ if (ConfMan.getInt(chosenConfVolumeSoundKey) != targetVol) {
+ ConfMan.setInt(chosenConfVolumeSoundKey, targetVol);
+ syncSoundSettings();
}
break;
@@ -1079,12 +1069,17 @@ bool ToonEngine::showOptions() {
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
- _textSpeed = entries[clickingOnSprite].targetFrame * 255 / (entries[clickingOnSprite].animation->_numFrames - 1);
+ targetTextSpeed = 0;
+ targetTextSpeed = entries[clickingOnSprite].targetFrame * 255 / (entries[clickingOnSprite].animation->_numFrames - 1);
// Since we use integer division, find a value for _textSpeed that will produce the same targetFrame we have calculated
// We need this value for setting the proper frame for the slider needle indicator, when resuming the Options menu.
- while (entries[clickingOnSprite].targetFrame > _textSpeed * (entries[clickingOnSprite].animation->_numFrames - 1) / 255)
- ++_textSpeed;
- // TODO store textSpeed
+ while (entries[clickingOnSprite].targetFrame > targetTextSpeed * (entries[clickingOnSprite].animation->_numFrames - 1) / 255)
+ ++targetTextSpeed;
+
+ if (ConfMan.getInt("talkspeed") != targetTextSpeed) {
+ ConfMan.setInt("talkspeed", targetTextSpeed);
+ syncSoundSettings();
+ }
break;
default:
@@ -1120,26 +1115,25 @@ bool ToonEngine::showOptions() {
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSIC)
- _audioManager->muteMusic(false);
+ ConfMan.setBool("music_mute", false);
else if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICE)
- _audioManager->muteVoice(false);
+ ConfMan.setBool("speech_mute", false);
else
- _audioManager->muteSfx(false);
+ ConfMan.setBool("sfx_mute", false);
+ syncSoundSettings();
} else {
entries[clickingOnSprite].targetFrame = 0;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSIC) {
- _audioManager->muteMusic(true);
+ ConfMan.setBool("music_mute", true);
} else if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICE) {
- _audioManager->muteVoice(true);
- if (!_showConversationText) {
- turnOnText(true, false);
- }
+ ConfMan.setBool("speech_mute", true);
} else
- _audioManager->muteSfx(true);
+ ConfMan.setBool("sfx_mute", true);
+ syncSoundSettings();
}
- adjustMovieVolume();
+
if (!_isEnglishDemo)
playSFX(-7, 128);
break;
@@ -1176,21 +1170,22 @@ bool ToonEngine::showOptions() {
if (!_isEnglishDemo) {
if ((ratioY <= 151 && ratioX >= 88 && ratioX <= 169)
|| (ratioY > 151 && ratioX >= 122 && ratioX <= 145) ) {
- turnOnText(false);
- if (_audioManager->isVoiceMuted()
- || _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) == 0) {
- turnOnText(true, false);
- }
+ ConfMan.setBool("subtitles", false);
+ syncSoundSettings();
entries[clickingOnSprite].targetFrame = 4;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
} else if (ratioY > 151 && ratioX > 145) {
- turnOnText(true, true);
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("alternative_font", true);
+ syncSoundSettings();
entries[clickingOnSprite].targetFrame = 8;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
} else if (ratioY > 151 && ratioX < 122) {
- turnOnText(true, false);
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("alternative_font", false);
+ syncSoundSettings();
entries[clickingOnSprite].targetFrame = 0;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
@@ -1203,18 +1198,16 @@ bool ToonEngine::showOptions() {
// toggles between "Text Off" and "Text On"
switch (entries[clickingOnSprite].activeFrame) {
case 0:
- turnOnText(true, false);
+ ConfMan.setBool("subtitles", true);
+ syncSoundSettings();
entries[clickingOnSprite].targetFrame = 8;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
break;
case 8:
- turnOnText(false);
- if (_audioManager->isVoiceMuted()
- || _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) == 0) {
- turnOnText(true, false);
- }
+ ConfMan.setBool("subtitles", false);
+ syncSoundSettings();
entries[clickingOnSprite].targetFrame = 0;
entries[clickingOnSprite].animateOnFrame = 1;
entries[clickingOnSprite].playOnce = true;
@@ -1507,13 +1500,6 @@ bool ToonEngine::showQuitConfirmationDialogue() {
return (dialog.runModal() == GUI::kMessageOK);
}
-void ToonEngine::adjustMovieVolume() {
- int movieVol = MAX<int>((_audioManager->isMusicMuted() ? 0 : _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType)),
- (_audioManager->isVoiceMuted() ? 0 : _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType)));
- movieVol = MAX<int>(movieVol,(_audioManager->isSfxMuted() ? 0 : _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType)));
- _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, movieVol);
-}
-
Common::Error ToonEngine::run() {
if (!loadToonDat())
@@ -2608,12 +2594,6 @@ void ToonEngine::setFont(bool alternative) {
_useAlternativeFont = alternative;
}
-void ToonEngine::turnOnText(bool enable, bool useAlternativeFont) {
- _showConversationText = enable;
- if (_showConversationText && !_isEnglishDemo)
- setFont(useAlternativeFont);
-}
-
void ToonEngine::drawInfoLine() {
if (_currentHotspotItem != 0 && !_gameState->_mouseHidden && !_gameState->_inConversation) {
const char *infoTool = NULL;
@@ -3761,6 +3741,16 @@ bool ToonEngine::saveGame(int32 slot, const Common::String &saveGameDesc) {
int16 savegameId;
Common::String savegameDescription;
+
+ // NOTE The original game engine additionally saved in EACH saved game file:
+ // - volume levels for music, speech and SFX
+ // - muted state for music, speech and SFX
+ // - text speed
+ // - disabled subtitles (text off) -- but not font selection.
+ // ScummVM skips saving (and restoring) this per saved game file.
+ // Instead it keeps these settings persisted and synced with
+ // ScummVM's ConfMan volume levels, text speed, and subtitles settings.
+
if (slot == -1) {
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
savegameId = dialog->runModalWithCurrentTarget();
@@ -5508,6 +5498,78 @@ void ToonEngine::clearDirtyRects() {
_dirtyRects.clear();
_dirtyAll = false;
}
+
+
+void ToonEngine::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ _mixer->setVolumeForSoundType(_mixer->kMusicSoundType, ConfMan.getInt("music_volume"));
+ _mixer->setVolumeForSoundType(_mixer->kSpeechSoundType, ConfMan.getInt("speech_volume"));
+ _mixer->setVolumeForSoundType(_mixer->kSFXSoundType, ConfMan.getInt("sfx_volume"));
+
+ if (_noMusicDriver) {
+ // This affects *only* the music muting.
+ _mixer->muteSoundType(_mixer->kMusicSoundType, true);
+ _audioManager->muteMusic(true);
+ }
+
+ bool allSoundIsMuted = false;
+ if (ConfMan.hasKey("mute")) {
+ allSoundIsMuted = ConfMan.getBool("mute");
+ if (!_noMusicDriver) {
+ _mixer->muteSoundType(_mixer->kMusicSoundType, allSoundIsMuted);
+ _audioManager->muteMusic(true);
+ }
+ _mixer->muteSoundType(_mixer->kSpeechSoundType, allSoundIsMuted);
+ _audioManager->muteVoice(true);
+ _mixer->muteSoundType(_mixer->kSFXSoundType, allSoundIsMuted);
+ _audioManager->muteSfx(true);
+ // movie sound type
+ _mixer->muteSoundType(_mixer->kPlainSoundType, allSoundIsMuted);
+ }
+
+ if (ConfMan.hasKey("music_mute") && !allSoundIsMuted) {
+ if (!_noMusicDriver) {
+ _mixer->muteSoundType(_mixer->kMusicSoundType, ConfMan.getBool("music_mute"));
+ _audioManager->muteMusic(ConfMan.getBool("music_mute"));
+ }
+ }
+
+ if (ConfMan.hasKey("speech_mute") && !allSoundIsMuted) {
+ _mixer->muteSoundType(_mixer->kSpeechSoundType, ConfMan.getBool("speech_mute"));
+ _audioManager->muteVoice(ConfMan.getBool("speech_mute"));
+ }
+
+ if (ConfMan.hasKey("sfx_mute") && !allSoundIsMuted) {
+ _mixer->muteSoundType(_mixer->kSFXSoundType, ConfMan.getBool("sfx_mute"));
+ _audioManager->muteSfx(ConfMan.getBool("sfx_mute"));
+ }
+
+ // Adjust movie volume
+ if (!allSoundIsMuted) {
+ int movieVol = MAX<int>((_audioManager->isMusicMuted() ? 0 : ConfMan.getInt("music_volume")),
+ (_audioManager->isVoiceMuted() ? 0 : ConfMan.getInt("speech_volume")));
+ movieVol = MAX<int>(movieVol,(_audioManager->isSfxMuted() ? 0 : ConfMan.getInt("sfx_volume")));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, movieVol);
+ }
+
+ _showConversationText = ConfMan.getBool("subtitles");
+ if (_showConversationText && !_isEnglishDemo) {
+ setFont(ConfMan.getBool("alternative_font"));
+ }
+
+ if ((ConfMan.getInt("speech_volume") == 0 || ConfMan.getBool("speech_mute") || allSoundIsMuted)
+ && !_showConversationText) {
+ ConfMan.setBool("subtitles", true);
+ _showConversationText = true;
+ }
+
+ _textSpeed = ConfMan.getInt("talkspeed");
+
+ // write-back to ini file for persistence
+ ConfMan.flushToDisk();
+}
+
void SceneAnimation::save(ToonEngine *vm, Common::WriteStream *stream) {
stream->writeByte(_active);
stream->writeSint32BE(_id);
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index d4357a63922..f5c6d428855 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -112,7 +112,6 @@ public:
bool showMainmenu(bool &loadedGame);
bool showOptions();
bool showQuitConfirmationDialogue();
- void adjustMovieVolume();
void init();
bool loadToonDat();
char **loadTextsVariants(Common::File &in);
@@ -215,7 +214,7 @@ public:
bool canSaveGameStateCurrently() override;
bool canLoadGameStateCurrently() override;
void pauseEngineIntern(bool pause) override;
- void turnOnText(bool enable, bool useAlternativeFont = false);
+ void syncSoundSettings() override;
Resources *resources() {
return _resources;
@@ -333,6 +332,7 @@ public:
bool hasFeature(EngineFeature f) const override {
return
+ (f == kSupportsSubtitleOptions) ||
(f == kSupportsReturnToLauncher) ||
(f == kSupportsLoadingDuringRuntime) ||
(f == kSupportsSavingDuringRuntime);
@@ -445,6 +445,7 @@ protected:
int _textSpeed;
bool _useAlternativeFont;
bool _needPaletteFlush;
+ bool _noMusicDriver; // If "Music Device" is set to "No Music" from Audio tab
};
} // End of namespace Toon
Commit: 8dec0798f54f1c2b1d6938ab147ff217c71dd57b
https://github.com/scummvm/scummvm/commit/8dec0798f54f1c2b1d6938ab147ff217c71dd57b
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-06-12T15:15:55+02:00
Commit Message:
TOON: Fix click on Play to resume resulting in Drew walking
If the player clicked and holded the left mouse button down on Play button, in-game Drew would walk to that spot
Changed paths:
engines/toon/toon.cpp
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 3145c68a7cc..7e2cc8ead94 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -918,18 +918,17 @@ bool ToonEngine::showOptions() {
oldMouseY = _mouseY;
oldMouseButton = _mouseButton;
- // update mouse clicking state and handle hotkeys
- parseInput();
-
- // NOTE Placing the code here seems to mitigate the issue
- // of clicking Play to resume playing and Drew moving to
- // that spot in-game.
- // It still happens if mouse button is held down.
if (_shouldQuit || doExitMenu) {
clickingOn = OPTIONMENUHOTSPOT_NONE;
clickRelease = true;
doExitMenu = true;
+ // Prevent holding left mouse button down to be detected
+ // as a new click when returning from menu
+ _lastMouseButton = _mouseButton;
} else {
+ // update mouse clicking state and handle hotkeys
+ parseInput();
+
copyToVirtualScreen(true);
if (_firstFrame) {
_firstFrame = false;
@@ -1340,13 +1339,17 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
oldMouseButton = _mouseButton;
- parseInput();
-
if (_shouldQuit || doExitMenu) {
clickingOn = MAINMENUHOTSPOT_NONE;
clickRelease = true;
doExitMenu = true;
+ // Prevent holding left mouse button down to be detected
+ // as a new click when returning from menu
+ _lastMouseButton = _mouseButton;
} else {
+ // update mouse clicking state and handle hotkeys
+ parseInput();
+
copyToVirtualScreen(true);
_system->delayMillis(17);
@@ -2255,6 +2258,7 @@ void ToonEngine::clickEvent() {
if (_pathFinding->findClosestWalkingPoint(_mouseX + _gameState->_currentScrollValue , _mouseY, &xx, &yy))
_drew->walkTo(xx, yy);
+
return;
}
Commit: 1380d40161dbaf93e87d1ea329fe15d56c7b2745
https://github.com/scummvm/scummvm/commit/1380d40161dbaf93e87d1ea329fe15d56c7b2745
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-06-12T15:15:55+02:00
Commit Message:
TOON: Don't display cutscene subtitles when text is OFF
Cutscene subtitles support is implemented but subtitles are still work in progress
I was able to test with subtitles provided by rzil (BLooperZ) in this PR:
https://github.com/scummvm/scummvm/pull/1887
Changed paths:
engines/toon/subtitles.cpp
engines/toon/toon.cpp
engines/toon/toon.h
diff --git a/engines/toon/subtitles.cpp b/engines/toon/subtitles.cpp
index d206a3451f8..660756fd166 100644
--- a/engines/toon/subtitles.cpp
+++ b/engines/toon/subtitles.cpp
@@ -37,7 +37,7 @@ SubtitleRenderer::~SubtitleRenderer() {
void SubtitleRenderer::render(const Graphics::Surface &frame, uint32 frameNumber, byte color) {
- if (!_hasSubtitles || _tw.empty()) {
+ if (!_hasSubtitles || _tw.empty() || !_vm->showConversationText()) {
return;
}
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 7e2cc8ead94..a7840fc312e 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -3699,6 +3699,10 @@ void ToonEngine::drawCustomText(int16 x, int16 y, const char *line, Graphics::Su
}
}
+bool ToonEngine::showConversationText() const {
+ return _showConversationText;
+}
+
void ToonEngine::pauseEngineIntern(bool pause) {
Engine::pauseEngineIntern(pause);
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index f5c6d428855..c4696bc4a45 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -211,6 +211,7 @@ public:
void waitForScriptStep();
void doMagnifierEffect();
void drawCustomText(int16 x, int16 y, const char *line, Graphics::Surface *frame, byte color);
+ bool showConversationText() const;
bool canSaveGameStateCurrently() override;
bool canLoadGameStateCurrently() override;
void pauseEngineIntern(bool pause) override;
More information about the Scummvm-git-logs
mailing list