diff options
Diffstat (limited to 'engines/titanic')
-rw-r--r-- | engines/titanic/carry/mouth.cpp | 5 | ||||
-rw-r--r-- | engines/titanic/game/bridge_view.cpp | 5 | ||||
-rw-r--r-- | engines/titanic/game/chicken_dispensor.cpp | 9 | ||||
-rw-r--r-- | engines/titanic/game/fan_control.cpp | 2 | ||||
-rw-r--r-- | engines/titanic/game_manager.cpp | 2 | ||||
-rw-r--r-- | engines/titanic/main_game_window.cpp | 6 | ||||
-rw-r--r-- | engines/titanic/npcs/titania.cpp | 13 | ||||
-rw-r--r-- | engines/titanic/sound/qmixer.cpp | 22 | ||||
-rw-r--r-- | engines/titanic/sound/sound_manager.cpp | 2 | ||||
-rw-r--r-- | engines/titanic/sound/wave_file.cpp | 9 | ||||
-rw-r--r-- | engines/titanic/sound/wave_file.h | 6 | ||||
-rw-r--r-- | engines/titanic/support/credit_text.cpp | 2 | ||||
-rw-r--r-- | engines/titanic/titanic.cpp | 62 | ||||
-rw-r--r-- | engines/titanic/titanic.h | 10 |
14 files changed, 119 insertions, 36 deletions
diff --git a/engines/titanic/carry/mouth.cpp b/engines/titanic/carry/mouth.cpp index d750fc969e..1b2830b99e 100644 --- a/engines/titanic/carry/mouth.cpp +++ b/engines/titanic/carry/mouth.cpp @@ -74,6 +74,11 @@ bool CMouth::PETGainedObjectMsg(CPETGainedObjectMsg *msg) { _field13C = true; } + // WORKAROUND: If Mouth is removed from Titania after inserting, + // message the Titania control so it can be flagged as removed + CTakeHeadPieceMsg headpieceMsg(getName()); + headpieceMsg.execute("TitaniaControl"); + return true; } diff --git a/engines/titanic/game/bridge_view.cpp b/engines/titanic/game/bridge_view.cpp index e8d70c8c43..14361b4e8c 100644 --- a/engines/titanic/game/bridge_view.cpp +++ b/engines/titanic/game/bridge_view.cpp @@ -55,6 +55,7 @@ bool CBridgeView::ActMsg(CActMsg *msg) { } else if (msg->_action == "Go") { _action = BA_GO; setVisible(true); + hideMouse(); volumeMsg._volume = 100; volumeMsg.execute("EngineSounds"); onMsg.execute("EngineSounds"); @@ -67,10 +68,13 @@ bool CBridgeView::ActMsg(CActMsg *msg) { if (msg->_action == "Cruise") { _action = BA_CRUISE; setVisible(true); + hideMouse(); playMovie(MOVIE_NOTIFY_OBJECT); } else if (msg->_action == "GoEnd") { _action = BA_ENDING1; setVisible(true); + hideMouse(); + CChangeMusicMsg musicMsg; musicMsg._flags = 1; musicMsg.execute("BridgeAutoMusicPlayer"); @@ -90,6 +94,7 @@ bool CBridgeView::MovieEndMsg(CMovieEndMsg *msg) { case BA_GO: case BA_CRUISE: setVisible(false); + showMouse(); decTransitions(); break; diff --git a/engines/titanic/game/chicken_dispensor.cpp b/engines/titanic/game/chicken_dispensor.cpp index 89873dcc4d..d44bc7157b 100644 --- a/engines/titanic/game/chicken_dispensor.cpp +++ b/engines/titanic/game/chicken_dispensor.cpp @@ -104,7 +104,7 @@ bool CChickenDispensor::StatusChangeMsg(CStatusChangeMsg *msg) { } bool CChickenDispensor::MovieEndMsg(CMovieEndMsg *msg) { - int movieFrame = getMovieFrame(); + int movieFrame = msg->_endFrame; if (movieFrame == 16) { // Dispensed a chicken @@ -113,12 +113,7 @@ bool CChickenDispensor::MovieEndMsg(CMovieEndMsg *msg) { CActMsg actMsg("Dispense Chicken"); actMsg.execute("Chicken"); - if (_dispenseMode == DISPENSE_HOT) { - // A properly hot chicken is dispensed, no further ones will be - // until the current one is used up, and the fuse in Titania's - // fusebox is removed and replaced - _dispenseMode = DISPENSE_NONE; - } else { + if (_dispenseMode != DISPENSE_HOT) { // WORKAROUND: If the fuse for the dispensor is removed in Titania's fusebox, // make the dispensed chicken already cold CChicken::_temperature = 0; diff --git a/engines/titanic/game/fan_control.cpp b/engines/titanic/game/fan_control.cpp index 7ed22fd560..fc99bd8b36 100644 --- a/engines/titanic/game/fan_control.cpp +++ b/engines/titanic/game/fan_control.cpp @@ -107,7 +107,7 @@ bool CFanControl::StatusChangeMsg(CStatusChangeMsg *msg) { case 2: // Fan Speed button if (_fanOn) { - _state = (_state + 1) % 4; + _state = (_state + 1) % 3; switch (_state) { case 0: playMovie(18, 24, 0); diff --git a/engines/titanic/game_manager.cpp b/engines/titanic/game_manager.cpp index 13fe1d2872..65a2a278c8 100644 --- a/engines/titanic/game_manager.cpp +++ b/engines/titanic/game_manager.cpp @@ -81,8 +81,8 @@ void CGameManager::preLoad() { _timers.destroyContents(); _soundMaker = nullptr; - _trueTalkManager.preLoad(); _sound.preLoad(); + _trueTalkManager.preLoad(); } void CGameManager::postLoad(CProjectItem *project) { diff --git a/engines/titanic/main_game_window.cpp b/engines/titanic/main_game_window.cpp index 053712d412..cfea98cdf1 100644 --- a/engines/titanic/main_game_window.cpp +++ b/engines/titanic/main_game_window.cpp @@ -341,6 +341,12 @@ void CMainGameWindow::keyDown(Common::KeyState keyState) { _gameManager->_gameState.changeView(newView, nullptr); } + } else if (keyState.keycode == Common::KEYCODE_F5) { + // Show the GMM save dialog + g_vm->showScummVMSaveDialog(); + } else if (keyState.keycode == Common::KEYCODE_F7) { + // Show the GMM load dialog + g_vm->showScummVMRestoreDialog(); } else if (_inputAllowed) { _gameManager->_inputTranslator.keyDown(keyState); } diff --git a/engines/titanic/npcs/titania.cpp b/engines/titanic/npcs/titania.cpp index 70ca4bace6..d3e3395fc8 100644 --- a/engines/titanic/npcs/titania.cpp +++ b/engines/titanic/npcs/titania.cpp @@ -149,9 +149,10 @@ bool CTitania::ActMsg(CActMsg *msg) { playSound("z#47.wav", 100); changeView("Titania.Node 7.S", ""); + // Re-enable control, and reset bomb's volume back to normal 60% petShow(); enableMouse(); - CSetFrameMsg frameMsg; + CSetFrameMsg frameMsg(60); frameMsg.execute("Bomb"); } else if (msg->_action == "CheckHead") { @@ -173,8 +174,9 @@ bool CTitania::ActMsg(CActMsg *msg) { workingMsg3._value = _speechCentre ? "Working" : "Random"; } - if (_centralCore && _eye1 && _eye2 && _ear1 && _ear2 && _nose && _mouth - && _speechCentre && _olfactoryCentre && _auditoryCentre) { + if (_centralCore && _eye1 && _eye2 && _ear1 && _ear2 && _nose + && _mouth && _visionCentre && _speechCentre + && _olfactoryCentre && _auditoryCentre) { CProximity prox(Audio::Mixer::kSpeechSoundType); playSound("z#47.wav", prox); @@ -203,11 +205,14 @@ bool CTitania::EnterViewMsg(CEnterViewMsg *msg) { disableMouse(); petHide(); + // The Bomb uses the CSetFrameMsg as a hack for setting the volume. + // In case it's currently active, set it to a quieter 25% so that + // it won't obscure Titania's speech. CSetFrameMsg frameMsg; frameMsg._frameNumber = 25; frameMsg.execute("Bomb"); - playCutscene(0, 52); + playCutscene(0, 52); setVisible(false); CActMsg actMsg("TitaniaSpeech"); actMsg.execute("TitaniaSpeech"); diff --git a/engines/titanic/sound/qmixer.cpp b/engines/titanic/sound/qmixer.cpp index 5c511c3cae..beb1502ab4 100644 --- a/engines/titanic/sound/qmixer.cpp +++ b/engines/titanic/sound/qmixer.cpp @@ -208,18 +208,13 @@ void QMixer::qsWaveMixPump() { if (!channel._sounds.empty()) { SoundEntry &sound = channel._sounds.front(); if (sound._started && !_mixer->isSoundHandleActive(sound._soundHandle)) { - if (sound._loops == -1 || sound._loops-- > 0) { - // Need to loop (replay) the sound again - sound._soundHandle = sound._waveFile->play(channel.getRawVolume()); - } else { - // Sound is finished - if (sound._callback) - // Call the callback to signal end - sound._callback(iChannel, sound._waveFile, sound._userData); - - // Remove sound record from channel - channel._sounds.erase(channel._sounds.begin()); - } + // Sound is finished + if (sound._callback) + // Call the callback to signal end + sound._callback(iChannel, sound._waveFile, sound._userData); + + // Remove sound record from channel + channel._sounds.erase(channel._sounds.begin()); } } @@ -232,7 +227,8 @@ void QMixer::qsWaveMixPump() { channel._distance = 0.0; // Play the wave - sound._soundHandle = sound._waveFile->play(channel.getRawVolume()); + sound._soundHandle = sound._waveFile->play( + sound._loops, channel.getRawVolume()); sound._started = true; } } diff --git a/engines/titanic/sound/sound_manager.cpp b/engines/titanic/sound/sound_manager.cpp index 514618783b..4b5887b1e7 100644 --- a/engines/titanic/sound/sound_manager.cpp +++ b/engines/titanic/sound/sound_manager.cpp @@ -288,7 +288,7 @@ void QSoundManager::setVolume(int handle, uint volume, uint seconds) { _channelsVolume[slot._channel] = volume; updateVolume(slot._channel, seconds * 1000); - if (volume) { + if (!volume) { uint ticks = g_vm->_events->getTicksCount() + seconds * 1000; if (!slot._ticks || ticks >= slot._ticks) slot._ticks = ticks; diff --git a/engines/titanic/sound/wave_file.cpp b/engines/titanic/sound/wave_file.cpp index 8a4755ac97..c1aab42a7f 100644 --- a/engines/titanic/sound/wave_file.cpp +++ b/engines/titanic/sound/wave_file.cpp @@ -204,10 +204,15 @@ void CWaveFile::unlock(const int16 *ptr) { // No implementation needed in ScummVM } -Audio::SoundHandle CWaveFile::play(byte volume) { - Audio::SeekableAudioStream *stream = createAudioStream(); +Audio::SoundHandle CWaveFile::play(int numLoops, byte volume) { + Audio::SeekableAudioStream *audioStream = createAudioStream(); Audio::SoundHandle handle; + Audio::AudioStream *stream = audioStream; + if (numLoops != 0) + stream = new Audio::LoopingAudioStream(audioStream, + (numLoops == -1) ? 0 : numLoops); + _mixer->playStream(_soundType, &handle, stream, -1, volume, 0, DisposeAfterUse::NO); return handle; diff --git a/engines/titanic/sound/wave_file.h b/engines/titanic/sound/wave_file.h index 17c7b62f4b..c14891e2e4 100644 --- a/engines/titanic/sound/wave_file.h +++ b/engines/titanic/sound/wave_file.h @@ -126,8 +126,12 @@ public: /** * Plays the wave file + * @param numLoops Number of times to loop. 0 for none, + * -1 for infinite, and >0 for specified number of times + * @param volume Volume to play at + * @returns Audio handle for started sound */ - Audio::SoundHandle play(byte volume); + Audio::SoundHandle play(int numLoops, byte volume); }; } // End of namespace Titanic diff --git a/engines/titanic/support/credit_text.cpp b/engines/titanic/support/credit_text.cpp index 98c3d9bf1d..6ee17a2b95 100644 --- a/engines/titanic/support/credit_text.cpp +++ b/engines/titanic/support/credit_text.cpp @@ -96,7 +96,7 @@ void CCreditText::setup() { _screenManagerP->setFontNumber(oldFontNumber); _groupIt = _groups.begin(); _lineIt = (*_groupIt)->_lines.begin(); - _yOffset = _objectP->getBounds().height() + _fontHeight * 2; + _yOffset = _objectP->_bounds.height() + _fontHeight * 2; } CString CCreditText::readLine(Common::SeekableReadStream *stream) { diff --git a/engines/titanic/titanic.cpp b/engines/titanic/titanic.cpp index 8a1b00c0fc..b6ee868877 100644 --- a/engines/titanic/titanic.cpp +++ b/engines/titanic/titanic.cpp @@ -25,9 +25,11 @@ #include "common/config-manager.h" #include "common/debug-channels.h" #include "common/events.h" +#include "common/translation.h" #include "engines/util.h" #include "graphics/scaler.h" #include "graphics/thumbnail.h" +#include "gui/saveload.h" #include "titanic/titanic.h" #include "titanic/debugger.h" #include "titanic/carry/hose.h" @@ -179,23 +181,30 @@ bool TitanicEngine::canLoadGameStateCurrently() { CGameManager *gameManager = _window->_gameManager; CScreenManager *screenMan = CScreenManager::_screenManagerPtr; - if (!_window->_inputAllowed || !gameManager->_gameState._petActive) + if (!_window->_inputAllowed) return false; if (screenMan && screenMan->_inputHandler->isLocked()) return false; CProjectItem *project = gameManager->_project; if (project) { - CPetControl *pet = project->getPetControl(); - if (pet && !pet->isAreaUnlocked()) - return false; + if (gameManager->_gameState._petActive) { + CPetControl *pet = project->getPetControl(); + if (pet && !pet->isAreaUnlocked()) + return false; + } + } else { + return false; } return true; } bool TitanicEngine::canSaveGameStateCurrently() { - return canLoadGameStateCurrently(); + CGameManager *gameManager = _window->_gameManager; + + return gameManager->_gameState._petActive && + canLoadGameStateCurrently(); } Common::Error TitanicEngine::loadGameState(int slot) { @@ -251,4 +260,47 @@ void TitanicEngine::GUIError(const char *msg, ...) { GUIErrorMessage(buffer); } + +void TitanicEngine::showScummVMSaveDialog() { + if (!canSaveGameStateCurrently()) + return; + + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); + + pauseEngine(true); + int slot = dialog->runModalWithCurrentTarget(); + pauseEngine(false); + + if (slot >= 0) { + Common::String desc = dialog->getResultString(); + + if (desc.empty()) { + // create our own description for the saved game, the user didn't enter it + desc = dialog->createDefaultSaveDescription(slot); + } + + // Save the game + saveGameState(slot, desc); + } + + delete dialog; +} + +void TitanicEngine::showScummVMRestoreDialog() { + if (!canLoadGameStateCurrently()) + return; + + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); + + pauseEngine(true); + int slot = dialog->runModalWithCurrentTarget(); + pauseEngine(false); + + if (slot >= 0) { + loadGameState(slot); + } + + delete dialog; +} + } // End of namespace Titanic diff --git a/engines/titanic/titanic.h b/engines/titanic/titanic.h index dc7fd156b8..0c15cf3e72 100644 --- a/engines/titanic/titanic.h +++ b/engines/titanic/titanic.h @@ -191,6 +191,16 @@ public: * Displays an error message in a GUI dialog */ void GUIError(const char *msg, ...) GCC_PRINTF(2, 3); + + /** + * Shows the ScummVM GMM save dialog + */ + void showScummVMSaveDialog(); + + /** + * Shows the ScummVM GMM load dialog + */ + void showScummVMRestoreDialog(); }; extern TitanicEngine *g_vm; |