aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/mohawk/riven.cpp3
-rw-r--r--engines/saga/actor.cpp15
-rw-r--r--engines/saga/interface.cpp16
-rw-r--r--engines/saga/script.cpp19
-rw-r--r--engines/saga/sfuncs.cpp8
-rw-r--r--engines/sludge/sound.cpp151
-rw-r--r--engines/sludge/sound.h8
-rw-r--r--engines/sludge/sprites.cpp14
-rw-r--r--engines/titanic/carry/mouth.cpp5
-rw-r--r--engines/titanic/game/bridge_view.cpp5
-rw-r--r--engines/titanic/game/chicken_dispensor.cpp9
-rw-r--r--engines/titanic/game/fan_control.cpp2
-rw-r--r--engines/titanic/game_manager.cpp2
-rw-r--r--engines/titanic/main_game_window.cpp6
-rw-r--r--engines/titanic/npcs/titania.cpp13
-rw-r--r--engines/titanic/sound/qmixer.cpp22
-rw-r--r--engines/titanic/sound/sound_manager.cpp2
-rw-r--r--engines/titanic/sound/wave_file.cpp9
-rw-r--r--engines/titanic/sound/wave_file.h6
-rw-r--r--engines/titanic/support/credit_text.cpp2
-rw-r--r--engines/titanic/titanic.cpp62
-rw-r--r--engines/titanic/titanic.h10
-rw-r--r--engines/wage/detection_tables.h1
-rw-r--r--engines/wage/script.cpp11
24 files changed, 204 insertions, 197 deletions
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index c7f8d1c3d9..ea3e2ce7ec 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -510,7 +510,10 @@ void MohawkEngine_Riven::delay(uint32 ms) {
void MohawkEngine_Riven::runLoadDialog() {
GUI::SaveLoadChooser slc(_("Load game:"), _("Load"), false);
+ pauseEngine(true);
int slot = slc.runModalWithCurrentTarget();
+ pauseEngine(false);
+
if (slot >= 0) {
loadGameStateAndDisplayError(slot);
}
diff --git a/engines/saga/actor.cpp b/engines/saga/actor.cpp
index d8b115f9bd..8c45a2890e 100644
--- a/engines/saga/actor.cpp
+++ b/engines/saga/actor.cpp
@@ -1174,21 +1174,6 @@ void Actor::actorSpeech(uint16 actorId, const char **strings, int stringsCount,
_activeSpeech.speechBox.right = _vm->getDisplayInfo().width - 10;
}
- // HACK for the compact disk in Ellen's chapter
- // Once Ellen starts saying that "Something is different", bring the compact disk in the
- // scene. After speaking with AM, the compact disk is visible. She always says this line
- // when entering room 59, after speaking with AM, if the compact disk is not picked up yet
- // Check Script::sfDropObject for the other part of this hack
- if (_vm->getGameId() == GID_IHNM && _vm->_scene->currentChapterNumber() == 3 &&
- _vm->_scene->currentSceneNumber() == 59 && _activeSpeech.sampleResourceId == 286) {
- for (ObjectDataArray::iterator obj = _objs.begin(); obj != _objs.end(); ++obj) {
- if (obj->_id == 16385) { // the compact disk
- obj->_sceneNumber = 59;
- break;
- }
- }
- }
-
}
void Actor::nonActorSpeech(const Common::Rect &box, const char **strings, int stringsCount, int sampleResourceId, int speechFlags) {
diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp
index 9dcc8d9137..e6b196c4cd 100644
--- a/engines/saga/interface.cpp
+++ b/engines/saga/interface.cpp
@@ -2533,10 +2533,12 @@ void Interface::converseDisplayTextLines() {
char bullet[2] = {
(char)0xb7, 0
};
- Rect rect(8, _vm->getDisplayInfo().converseTextLines * _vm->getDisplayInfo().converseTextHeight);
- Point textPoint;
assert(_conversePanel.buttonsCount >= 6);
+ Rect rect(8, _vm->getDisplayInfo().converseTextLines * _vm->getDisplayInfo().converseTextHeight);
+ rect.moveTo(_conversePanel.x + _conversePanel.buttons[0].xOffset, _conversePanel.y + _conversePanel.buttons[0].yOffset);
+
+ Point textPoint;
if (_vm->getGameId() == GID_ITE) {
bulletForegnd = kITEColorGreen;
@@ -2547,13 +2549,11 @@ void Interface::converseDisplayTextLines() {
bullet[0] = '>'; // different bullet in IHNM
}
- rect.moveTo(_conversePanel.x + _conversePanel.buttons[0].xOffset,
- _conversePanel.y + _conversePanel.buttons[0].yOffset);
-
if (_vm->getGameId() == GID_ITE)
- _vm->_gfx->drawRect(rect, kITEColorDarkGrey); //fill bullet place
- else
- _vm->_gfx->drawRect(rect, _vm->KnownColor2ColorId(kKnownColorBlack)); //fill bullet place
+ _vm->_gfx->drawRect(rect, kITEColorDarkGrey); // fill bullet place
+ else if (_vm->getGameId() == GID_IHNM)
+ // TODO: Add these to IHNM_DisplayInfo?
+ _vm->_gfx->drawRect(Common::Rect(118, 345, 603, 463), _vm->KnownColor2ColorId(kKnownColorBlack)); // fill converse rect
for (int i = 0; i < _vm->getDisplayInfo().converseTextLines; i++) {
relPos = _converseStartPos + i;
diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp
index 3cc6586432..7a84944b17 100644
--- a/engines/saga/script.cpp
+++ b/engines/saga/script.cpp
@@ -1709,15 +1709,16 @@ void Script::whichObject(const Point& mousePoint) {
if (_vm->getGameId() == GID_IHNM && objectId == 8199)
newRightButtonVerb = getVerbType(kVerbLookAt);
- if ((_currentVerb == getVerbType(kVerbPickUp)) ||
- (_currentVerb == getVerbType(kVerbOpen)) ||
- (_currentVerb == getVerbType(kVerbClose)) ||
- ((_currentVerb == getVerbType(kVerbGive)) && !_firstObjectSet) ||
- ((_currentVerb == getVerbType(kVerbUse)) && !(actor->_flags & kFollower))) {
- if (_vm->getGameId() == GID_ITE) {
- objectId = ID_NOTHING;
- newObjectId = ID_NOTHING;
- }
+ bool actorIsFollower = (actor->_flags & kFollower);
+ bool actorCanBeUsed = (actor->_flags & kUsable);
+
+ if ( _currentVerb == getVerbType(kVerbPickUp) ||
+ _currentVerb == getVerbType(kVerbOpen) ||
+ _currentVerb == getVerbType(kVerbClose) ||
+ (_currentVerb == getVerbType(kVerbGive) && !_firstObjectSet) ||
+ (_currentVerb == getVerbType(kVerbUse) && !_firstObjectSet && !(actorIsFollower || actorCanBeUsed))) {
+ objectId = ID_NOTHING;
+ newObjectId = ID_NOTHING;
}
}
}
diff --git a/engines/saga/sfuncs.cpp b/engines/saga/sfuncs.cpp
index 2175d8f40a..6456daeb02 100644
--- a/engines/saga/sfuncs.cpp
+++ b/engines/saga/sfuncs.cpp
@@ -704,14 +704,6 @@ void Script::sfDropObject(SCRIPTFUNC_PARAMS) {
obj->_sceneNumber = _vm->_scene->currentSceneNumber();
- // HACK for the compact disk in Ellen's chapter
- // Change the scene number of the compact disk so that it's not shown. It will be shown
- // once Ellen says that there's something different (i.e. after speaking with AM)
- // See Actor::actorSpeech for the other part of this hack
- if (_vm->getGameId() == GID_IHNM && _vm->_scene->currentChapterNumber() == 3 &&
- _vm->_scene->currentSceneNumber() == 59 && obj->_id == 16385)
- obj->_sceneNumber = -1;
-
if (_vm->getGameId() == GID_IHNM) {
// Don't update _spriteListResourceId if spriteId is 0 and the object is not the
// psychic profile. If spriteId == 0, the object's sprite is incorrectly reset.
diff --git a/engines/sludge/sound.cpp b/engines/sludge/sound.cpp
index 79b9ab79d8..6820ae14be 100644
--- a/engines/sludge/sound.cpp
+++ b/engines/sludge/sound.cpp
@@ -52,10 +52,9 @@ SoundManager::SoundManager() {
_soundCache = nullptr;
_soundCache = new SoundThing[MAX_SAMPLES];
- #if 0
+
_modCache = nullptr;
_modCache = new SoundThing[MAX_MODS];
- #endif
_defVol = 128;
_defSoundVol = 255;
@@ -70,10 +69,8 @@ SoundManager::~SoundManager() {
delete []_soundCache;
_soundCache = nullptr;
- #if 0
delete []_modCache;
_modCache = nullptr;
- #endif
}
bool SoundManager::initSoundStuff() {
@@ -82,12 +79,13 @@ bool SoundManager::initSoundStuff() {
_soundCache[a].looping = false;
_soundCache[a].inSoundList = false;
}
-#if 0
+
for (int a = 0; a < MAX_MODS; a ++) {
- _modCache[a].stream = NULL;
- _modCache[a].playing = false;
+ _soundCache[a].fileLoaded = -1;
+ _soundCache[a].looping = false;
+ _soundCache[a].inSoundList = false;
}
-#endif
+
return _soundOK = true;
}
@@ -95,48 +93,24 @@ void SoundManager::killSoundStuff() {
if (!_soundOK)
return;
- _silenceIKillYou = true;
- for (int i = 0; i < MAX_SAMPLES; i ++) {
- if (g_sludge->_mixer->isSoundHandleActive(_soundCache[i].handle)) {
- g_sludge->_mixer->stopHandle(_soundCache[i].handle);
- }
- }
-#if 0
- for (int i = 0; i < MAX_MODS; i ++) {
- if (_modCache[i].playing) {
-
- if (! alureStopSource(modCache[i].playingOnSource, AL_TRUE)) {
- debugOut("Failed to stop source: %s\n",
- alureGetErrorString());
- }
-
- }
-
- if (_modCache[i].stream != NULL) {
-
- if (! alureDestroyStream(modCache[i].stream, 0, NULL)) {
- debugOut("Failed to destroy stream: %s\n",
- alureGetErrorString());
- }
+ for (int i = 0; i < MAX_SAMPLES; ++i)
+ freeSound(i);
- }
- }
-#endif
- _silenceIKillYou = false;
+ for (int i = 0; i < MAX_MODS; ++i)
+ stopMOD(i);
}
/*
* Some setters:
*/
-
void SoundManager::setMusicVolume(int a, int v) {
if (!_soundOK)
return;
-#if 0
- if (_modCache[a].playing) {
- alSourcef(modCache[a].playingOnSource, AL_GAIN, (float) _modLoudness * v / 256);
+
+ if (g_sludge->_mixer->isSoundHandleActive(_modCache[a].handle)) {
+ _modCache[a].vol = v;
+ g_sludge->_mixer->setChannelVolume(_modCache[a].handle, _modLoudness * v / 256);
}
-#endif
}
void SoundManager::setDefaultMusicVolume(int v) {
@@ -176,14 +150,11 @@ int SoundManager::findInSoundCache(int a) {
void SoundManager::stopMOD(int i) {
if (!_soundOK)
return;
-#if 0
- alGetError();
- if (modCache[i].playing) {
- if (! alureStopSource(modCache[i].playingOnSource, AL_TRUE)) {
- debugOut("Failed to stop source: %s\n", alureGetErrorString());
- }
+
+ if (g_sludge->_mixer->isSoundHandleActive(_modCache[i].handle)) {
+ g_sludge->_mixer->stopHandle(_modCache[i].handle);
}
-#endif
+ _modCache[i].fileLoaded = -1;
}
void SoundManager::huntKillSound(int filenum) {
@@ -191,15 +162,10 @@ void SoundManager::huntKillSound(int filenum) {
return;
int gotSlot = findInSoundCache(filenum);
- if (gotSlot == -1) return;
-
- _silenceIKillYou = true;
-
- if (g_sludge->_mixer->isSoundHandleActive(_soundCache[gotSlot].handle)) {
- g_sludge->_mixer->stopHandle(_soundCache[gotSlot].handle);
- }
+ if (gotSlot == -1)
+ return;
- _silenceIKillYou = false;
+ freeSound(gotSlot);
}
void SoundManager::freeSound(int a) {
@@ -214,6 +180,8 @@ void SoundManager::freeSound(int a) {
handleSoundLists();
}
+ _soundCache[a].inSoundList = false;
+ _soundCache[a].looping = false;
_soundCache[a].fileLoaded = -1;
_silenceIKillYou = false;
@@ -233,69 +201,33 @@ void SoundManager::huntKillFreeSound(int filenum) {
*/
bool SoundManager::playMOD(int f, int a, int fromTrack) {
#if 0
+ if (!_soundOK)
+ return true;
+ stopMOD(a);
+
// load sound
setResourceForFatal(f);
- uint32 length = openFileFromNum(f);
+ uint length = g_sludge->_resMan->openFileFromNum(f);
if (length == 0) {
- finishAccess();
+ g_sludge->_resMan->finishAccess();
setResourceForFatal(-1);
return false;
}
- Common::SeekableReadStream *memImage = bigDataFile->readStream(length);
- if (memImage->size() != length || bigDataFile->err())
+ // make audio stream
+ Common::SeekableReadStream *readStream = g_sludge->_resMan->getData();
+ Common::SeekableReadStream *memImage = readStream->readStream(length);
+ if (memImage->size() != (int)length || readStream->err())
debug("Sound reading failed");
Audio::AudioStream *stream = Audio::makeProtrackerStream(memImage);
- //TODO: replace by xm file decoders
+
if (!stream)
return false;
// play sound
- Audio::SoundHandle soundHandle;
- g_sludge->_mixer->playStream(Audio::Mixer::kSFXSoundType, &soundHandle,
+ g_sludge->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_modCache[a].handle,
stream, -1, Audio::Mixer::kMaxChannelVolume);
- if (!_soundOK)
- return true;
- stopMOD(a);
-
- setResourceForFatal(f);
- uint32 length = openFileFromNum(f);
- if (length == 0) {
- finishAccess();
- setResourceForFatal(-1);
- return false;
- }
-
- byte *memImage;
- memImage = (byte *) loadEntireFileToMemory(bigDataFile, length);
- if (! memImage) return fatal(ERROR_MUSIC_MEMORY_LOW);
-
- _modCache[a].stream = alureCreateStreamFromMemory(memImage, length, 19200, 0, NULL);
-
- delete memImage;
-
- if (_modCache[a].stream != NULL) {
- setMusicVolume(a, defVol);
-
- if (! alureSetStreamOrder(modCache[a].stream, fromTrack)) {
- debugOut("Failed to set stream order: %s\n",
- alureGetErrorString());
- }
-
- playStream(a, true, true);
-
- } else {
-
- debugOut("Failed to create stream from MOD: %s\n",
- alureGetErrorString());
-
- warning(ERROR_MUSIC_ODDNESS);
- _soundCache[a].stream = NULL;
- _soundCache[a].playing = false;
- _soundCache[a].playingOnSource = 0;
- }
- setResourceForFatal(-1);
#endif
return true;
}
@@ -363,20 +295,12 @@ int SoundManager::makeSoundAudioStream(int f, Audio::AudioStream *&audiostream,
return -1;
int a = findInSoundCache(f);
- if (a != -1) { // if this sound has been loaded before
- // still playing
- if (g_sludge->_mixer->isSoundHandleActive(_soundCache[a].handle)) {
- g_sludge->_mixer->stopHandle(_soundCache[a].handle); // stop it
- if (_soundCache[a].inSoundList) {
- handleSoundLists();
- }
- }
- } else {
+ if (a == -1) {
if (f == -2)
return -1;
a = findEmptySoundSlot();
- freeSound(a);
}
+ freeSound(a);
setResourceForFatal(f);
uint32 length = g_sludge->_resMan->openFileFromNum(f);
@@ -398,6 +322,7 @@ int SoundManager::makeSoundAudioStream(int f, Audio::AudioStream *&audiostream,
if (stream) {
audiostream = Audio::makeLoopingAudioStream(stream, loopy ? 0 : 1);
_soundCache[a].fileLoaded = f;
+ _soundCache[a].looping = loopy;
setResourceForFatal(-1);
} else {
audiostream = nullptr;
diff --git a/engines/sludge/sound.h b/engines/sludge/sound.h
index cdd76b33cc..1e1a2a47e4 100644
--- a/engines/sludge/sound.h
+++ b/engines/sludge/sound.h
@@ -83,9 +83,9 @@ private:
struct SoundThing {
Audio::SoundHandle handle;
- int fileLoaded, vol; //Used for sounds only. (sound saving/loading)
- bool looping; //Used for sounds only. (sound saving/loading)
- bool inSoundList;
+ int fileLoaded, vol; //Used for wav/ogg sounds only. (sound saving/loading)
+ bool looping; //Used for wav/ogg sounds only. (sound saving/loading)
+ bool inSoundList; //Used for wav/ogg sounds only
};
typedef Common::List<SoundList *> SoundListHandles;
@@ -97,9 +97,7 @@ private:
bool _isHandlingSoundList;
SoundThing *_soundCache;
- #if 0
SoundThing *_modCache;
- #endif
int _defVol;
int _defSoundVol;
diff --git a/engines/sludge/sprites.cpp b/engines/sludge/sprites.cpp
index 98d88a8337..c37c4a1905 100644
--- a/engines/sludge/sprites.cpp
+++ b/engines/sludge/sprites.cpp
@@ -271,6 +271,13 @@ bool GraphicsManager::loadSpriteBank(int fileNum, SpriteBank &loadhere, bool isF
// pasteSpriteToBackDrop uses the colour specified by the setPasteColour (or setPasteColor)
void GraphicsManager::pasteSpriteToBackDrop(int x1, int y1, Sprite &single, const SpritePalette &fontPal) {
+ // kill zBuffer
+ if (_zBuffer->originalNum >= 0 && _zBuffer->sprites) {
+ int num = _zBuffer->originalNum;
+ killZBuffer();
+ _zBuffer->originalNum = num;
+ }
+
//TODO: shader: useLightTexture
x1 -= single.xhot;
y1 -= single.yhot;
@@ -282,6 +289,13 @@ void GraphicsManager::pasteSpriteToBackDrop(int x1, int y1, Sprite &single, cons
// burnSpriteToBackDrop adds text in the colour specified by setBurnColour
// using the differing brightness levels of the font to achieve an anti-aliasing effect.
void GraphicsManager::burnSpriteToBackDrop(int x1, int y1, Sprite &single, const SpritePalette &fontPal) {
+ // kill zBuffer
+ if (_zBuffer->originalNum >= 0 && _zBuffer->sprites) {
+ int num = _zBuffer->originalNum;
+ killZBuffer();
+ _zBuffer->originalNum = num;
+ }
+
//TODO: shader: useLightTexture
x1 -= single.xhot;
y1 -= single.yhot - 1;
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;
diff --git a/engines/wage/detection_tables.h b/engines/wage/detection_tables.h
index b207946882..bde10785df 100644
--- a/engines/wage/detection_tables.h
+++ b/engines/wage/detection_tables.h
@@ -158,7 +158,6 @@ static const ADGameDescription gameDescriptions[] = {
FANGAME("Star Trek", "3067332e6f0bb0314579f9bf102e1b56", 53320),
FANGAME("Strange Disappearance", "9d6e41b61c0fc90400e5da2fcb653a4a", 772282),
FANGAME("The Sultan's Palace", "fde31cbcc77b66969b4cfcd43075341e", 456855),
- // Code 0x03 in text
FANGAME("Swamp Witch", "bd8c8394be31f7845d55785b7ccfbbde", 739781), // Original file name "Swamp Witch†"
FANGAME("Swamp Witch", "07463c8b3b908b0c493a41b949ac1ff5", 740131), // alt version, normal file name
FANGAME("Sweetspace Now!", "574dc7dd25543f7a516d6524f0c5ab33", 123813), // Comes with Jumble
diff --git a/engines/wage/script.cpp b/engines/wage/script.cpp
index c4cf23fcb1..3405c8bf47 100644
--- a/engines/wage/script.cpp
+++ b/engines/wage/script.cpp
@@ -1161,12 +1161,19 @@ void Script::convertToText() {
break;
if (c < 0x80) {
- if (c < 0x20)
- error("convertToText: Unknown code 0x%02x at %d", c, _data->pos());
+ if (c < 0x20) {
+ warning("convertToText: Unknown code 0x%02x at %d", c, _data->pos());
+ c = ' ';
+ }
do {
scr->line += c;
c = _data->readByte();
+
+ if (c < 0x20) {
+ warning("convertToText: Unknown code 0x%02x at %d", c, _data->pos());
+ c = ' ';
+ }
} while (c < 0x80);
_data->seek(-1, SEEK_CUR);