aboutsummaryrefslogtreecommitdiff
path: root/engines/lastexpress/game/sound.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/lastexpress/game/sound.cpp')
-rw-r--r--engines/lastexpress/game/sound.cpp1951
1 files changed, 0 insertions, 1951 deletions
diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp
deleted file mode 100644
index 3f98ac79ea..0000000000
--- a/engines/lastexpress/game/sound.cpp
+++ /dev/null
@@ -1,1951 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "lastexpress/game/sound.h"
-
-#include "lastexpress/game/action.h"
-#include "lastexpress/game/entities.h"
-#include "lastexpress/game/inventory.h"
-#include "lastexpress/game/logic.h"
-#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/state.h"
-
-#include "lastexpress/helpers.h"
-#include "lastexpress/graphics.h"
-#include "lastexpress/lastexpress.h"
-#include "lastexpress/resource.h"
-
-namespace LastExpress {
-
-#define SOUNDCACHE_ENTRY_SIZE 92160
-#define SOUNDCACHE_MAX_SIZE 6
-
-// Letters & messages
-const char *messages[24] = {
- "",
- "TXT1001", // 1
- "TXT1001A", // 2
- "TXT1011", // 3
- "TXT1012", // 4
- "TXT1013", // 5
- "TXT1014", // 6
- "TXT1020", // 7
- "TXT1030", // 8
- "END1009B", // 50
- "END1046", // 51
- "END1047", // 52
- "END1112", // 53
- "END1112A", // 54
- "END1503", // 55
- "END1505A", // 56
- "END1505B", // 57
- "END1610", // 58
- "END1612A", // 59
- "END1612C", // 61
- "END1612D", // 62
- "ENDALRM1", // 63
- "ENDALRM2", // 64
- "ENDALRM3" // 65
-};
-
-const char *cities[17] = {
- "EPERNAY",
- "CHALONS",
- "BARLEDUC",
- "NANCY",
- "LUNEVILL",
- "AVRICOUR",
- "DEUTSCHA",
- "STRASBOU",
- "BADENOOS",
- "SALZBURG",
- "ATTNANG",
- "WELS",
- "LINZ",
- "VIENNA",
- "POZSONY",
- "GALANTA",
- "POLICE"
-};
-
-const char *locomotiveSounds[5] = {
- "ZFX1005",
- "ZFX1006",
- "ZFX1007",
- "ZFX1007A",
- "ZFX1007B"
-};
-
-static const SoundManager::FlagType soundFlags[32] = {
- SoundManager::kFlagDefault, SoundManager::kFlag15, SoundManager::kFlag14, SoundManager::kFlag13, SoundManager::kFlag12,
- SoundManager::kFlag11, SoundManager::kFlag11, SoundManager::kFlag10, SoundManager::kFlag10, SoundManager::kFlag9, SoundManager::kFlag9, SoundManager::kFlag8, SoundManager::kFlag8,
- SoundManager::kFlag7, SoundManager::kFlag7, SoundManager::kFlag7, SoundManager::kFlag6, SoundManager::kFlag6, SoundManager::kFlag6,
- SoundManager::kFlag5, SoundManager::kFlag5, SoundManager::kFlag5, SoundManager::kFlag5, SoundManager::kFlag4, SoundManager::kFlag4, SoundManager::kFlag4, SoundManager::kFlag4,
- SoundManager::kFlag3, SoundManager::kFlag3, SoundManager::kFlag3, SoundManager::kFlag3, SoundManager::kFlag3
-};
-
-SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine), _state(0), _currentType(kSoundType16), _flag(0) {
- // Initialize unknown data
- _data0 = 0;
- _data1 = 0;
- _data2 = 0;
-
- memset(&_buffer, 0, sizeof(_buffer));
- memset(&_lastWarning, 0, sizeof(_lastWarning));
-
- // Sound cache
- _soundCacheData = malloc(6 * SOUNDCACHE_ENTRY_SIZE);
-
- _drawSubtitles = 0;
- _currentSubtitle = NULL;
-}
-
-SoundManager::~SoundManager() {
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
- SAFE_DELETE(*i);
- _soundList.clear();
-
- // Entries in the cache are just pointers to sound list entries
- _soundCache.clear();
-
- for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i)
- SAFE_DELETE(*i);
- _subtitles.clear();
-
- _currentSubtitle = NULL;
-
- free(_soundCacheData);
-
- // Zero passed pointers
- _engine = NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Timer
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::handleTimer() {
- Common::StackLock locker(_mutex);
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- SoundEntry *entry = (*i);
- if (entry->stream == NULL) {
- SAFE_DELETE(*i);
- i = _soundList.reverse_erase(i);
- continue;
- } else if (!entry->soundStream) {
- entry->soundStream = new StreamedSound();
-
- // TODO: stream any sound in the queue after filtering
- entry->soundStream->load(entry->stream);
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Sound queue management
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::updateQueue() {
- // TODO add mutex lock!
- warning("Sound::updateQueue: not implemented!");
-}
-
-void SoundManager::resetQueue(SoundType type1, SoundType type2) {
- if (!type2)
- type2 = type1;
-
- Common::StackLock locker(_mutex);
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- if ((*i)->type != type1 && (*i)->type != type2)
- resetEntry(*i);
- }
-}
-
-void SoundManager::removeFromQueue(EntityIndex entity) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(entity);
- if (entry)
- resetEntry(entry);
-}
-
-void SoundManager::removeFromQueue(Common::String filename) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(filename);
- if (entry)
- resetEntry(entry);
-}
-
-void SoundManager::clearQueue() {
- _flag |= 4;
-
- // FIXME: Wait a while for a flag to be set
- //for (int i = 0; i < 3000000; i++)
- // if (_flag & 8)
- // break;
-
- _flag |= 8;
-
- Common::StackLock locker(_mutex);
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- SoundEntry *entry = (*i);
-
- // Delete entry
- removeEntry(entry);
- SAFE_DELETE(entry);
-
- i = _soundList.reverse_erase(i);
- }
-
- updateSubtitles();
-}
-
-bool SoundManager::isBuffered(EntityIndex entity) {
- Common::StackLock locker(_mutex);
-
- return (getEntry(entity) != NULL);
-}
-
-bool SoundManager::isBuffered(Common::String filename, bool testForEntity) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(filename);
-
- if (testForEntity)
- return entry != NULL && !entry->entity;
-
- return (entry != NULL);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Entry
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::setupEntry(SoundEntry *entry, Common::String name, FlagType flag, int a4) {
- if (!entry)
- error("SoundManager::setupEntry: Invalid entry!");
-
- entry->field_4C = a4;
- setEntryType(entry, flag);
- setEntryStatus(entry, flag);
-
- // Add entry to sound list
- _soundList.push_back(entry);
-
- // TODO Add entry to cache and load sound data
- //setupCache(entry);
- loadSoundData(entry, name);
-}
-
-void SoundManager::setEntryType(SoundEntry *entry, FlagType flag) {
- switch (flag & kFlagType9) {
- default:
- case kFlagNone:
- entry->type = _currentType;
- _currentType = (SoundType)(_currentType + 1);
- break;
-
- case kFlagType1_2: {
- SoundEntry *previous2 = getEntry(kSoundType2);
- if (previous2)
- updateEntry(previous2, 0);
-
- SoundEntry *previous = getEntry(kSoundType1);
- if (previous) {
- previous->type = kSoundType2;
- updateEntry(previous, 0);
- }
-
- entry->type = kSoundType1;
- }
- break;
-
- case kFlagType3: {
- SoundEntry *previous = getEntry(kSoundType3);
- if (previous) {
- previous->type = kSoundType4;
- updateEntry(previous, 0);
- }
-
- entry->type = kSoundType11;
- }
- break;
-
- case kFlagType7: {
- SoundEntry *previous = getEntry(kSoundType7);
- if (previous)
- previous->type = kSoundType8;
-
- entry->type = kSoundType7;
- }
- break;
-
- case kFlagType9: {
- SoundEntry *previous = getEntry(kSoundType9);
- if (previous)
- previous->type = kSoundType10;
-
- entry->type = kSoundType9;
- }
- break;
-
- case kFlagType11: {
- SoundEntry *previous = getEntry(kSoundType11);
- if (previous)
- previous->type = kSoundType14;
-
- entry->type = kSoundType11;
- }
- break;
-
- case kFlagType13: {
- SoundEntry *previous = getEntry(kSoundType13);
- if (previous)
- previous->type = kSoundType14;
-
- entry->type = kSoundType13;
- }
- break;
- }
-}
-
-void SoundManager::setEntryStatus(SoundEntry *entry, FlagType flag) const {
- SoundStatus status = (SoundStatus)flag;
- if (!((status & 0xFF) & kSoundStatusClear1))
- status = (SoundStatus)(status | kSoundStatusClear2);
-
- if (((status & 0xFF00) >> 8) & kSoundStatusClear0)
- entry->status.status = (uint32)status;
- else
- entry->status.status = (status | kSoundStatusClear4);
-}
-
-void SoundManager::setInCache(SoundEntry *entry) {
- entry->status.status |= kSoundStatusClear2;
-}
-
-bool SoundManager::setupCache(SoundEntry *entry) {
- if (entry->soundData)
- return true;
-
- if (_soundCache.size() >= SOUNDCACHE_MAX_SIZE) {
-
- SoundEntry *cacheEntry = NULL;
- uint32 size = 1000;
-
- for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
- if (!((*i)->status.status & kSoundStatus_180)) {
- uint32 newSize = (*i)->field_4C + ((*i)->status.status & kSoundStatusClear1);
-
- if (newSize < size) {
- cacheEntry = (*i);
- size = newSize;
- }
- }
- }
-
- if (entry->field_4C <= size)
- return false;
-
- if (cacheEntry)
- setInCache(cacheEntry);
-
- // TODO: Wait until the cache entry is ready to be removed
- while (!(cacheEntry->status.status1 & 1))
- ;
-
- if (cacheEntry->soundData)
- removeFromCache(cacheEntry);
-
- _soundCache.push_back(entry);
- entry->soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
- } else {
- _soundCache.push_back(entry);
- entry->soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
- }
-
- return true;
-}
-
-void SoundManager::removeFromCache(SoundEntry *entry) {
- for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
- if ((*i) == entry) {
- // Remove sound buffer
- entry->soundData = NULL;
-
- // Remove entry from sound cache
- i = _soundCache.reverse_erase(i);
- }
- }
-}
-
-void SoundManager::clearStatus() {
- Common::StackLock locker(_mutex);
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
- (*i)->status.status |= kSoundStatusClear3;
-}
-
-void SoundManager::loadSoundData(SoundEntry *entry, Common::String name) {
- entry->name2 = name;
-
- // Load sound data
- entry->stream = getArchive(name);
-
- if (!entry->stream)
- entry->stream = getArchive("DEFAULT.SND");
-
- if (entry->stream) {
- warning("Sound::loadSoundData: not implemented!");
- } else {
- entry->status.status = kSoundStatusRemoved;
- }
-}
-
-void SoundManager::resetEntry(SoundEntry *entry) const {
- entry->status.status |= kSoundStatusRemoved;
- entry->entity = kEntityPlayer;
-
- if (entry->stream) {
- if (!entry->soundStream) {
- SAFE_DELETE(entry->stream);
- } else {
- entry->soundStream->stop();
- SAFE_DELETE(entry->soundStream);
- }
-
- entry->stream = NULL;
- }
-}
-
-
-void SoundManager::removeEntry(SoundEntry *entry) {
- entry->status.status |= kSoundStatusRemoved;
-
- // Loop until ready
- while (!(entry->status.status1 & 4) && !(_flag & 8) && (_flag & 1))
- ; // empty loop body
-
- // The original game remove the entry from the cache here,
- // but since we are called from within an iterator loop
- // we will remove the entry there
- // removeFromCache(entry);
-
- if (entry->subtitle) {
- drawSubtitle(entry->subtitle);
- SAFE_DELETE(entry->subtitle);
- }
-
- if (entry->entity) {
- if (entry->entity == kEntitySteam)
- playLoopingSound();
- else if (entry->entity != kEntityTrain)
- getSavePoints()->push(kEntityPlayer, entry->entity, kActionEndSound);
- }
-}
-
-void SoundManager::updateEntry(SoundEntry *entry, uint value) const {
- if (!(entry->status.status3 & 64)) {
- int value2 = value;
-
- entry->status.status |= kSoundStatus_100000;
-
- if (value) {
- if (_flag & 32) {
- entry->field_40 = value;
- value2 = value * 2 + 1;
- }
-
- entry->field_3C = value2;
- } else {
- entry->field_3C = 0;
- entry->status.status |= kSoundStatus_40000000;
- }
- }
-}
-
-void SoundManager::updateEntryState(SoundEntry *entry) const {
- if (_flag & 32) {
- if (entry->type != kSoundType9 && entry->type != kSoundType7 && entry->type != kSoundType5) {
- uint32 status = entry->status.status & kSoundStatusClear1;
-
- entry->status.status &= kSoundStatusClearAll;
-
- entry->field_40 = status;
- entry->status.status |= status * 2 + 1;
- }
- }
-
- entry->status.status |= kSoundStatus_20;
-}
-
-void SoundManager::processEntry(EntityIndex entity) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(entity);
- if (entry) {
- updateEntry(entry, 0);
- entry->entity = kEntityPlayer;
- }
-}
-
-void SoundManager::processEntry(SoundType type) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(type);
- if (entry)
- updateEntry(entry, 0);
-}
-
-void SoundManager::setupEntry(SoundType type, EntityIndex index) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(type);
- if (entry)
- entry->entity = index;
-}
-
-void SoundManager::processEntry(Common::String filename) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(filename);
- if (entry) {
- updateEntry(entry, 0);
- entry->entity = kEntityPlayer;
- }
-}
-
-void SoundManager::processEntries() {
- _state = 0;
-
- processEntry(kSoundType1);
- processEntry(kSoundType2);
-}
-
-uint32 SoundManager::getEntryTime(EntityIndex index) {
- Common::StackLock locker(_mutex);
-
- SoundEntry *entry = getEntry(index);
- if (entry)
- return entry->time;
-
- return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Misc
-//////////////////////////////////////////////////////////////////////////
-
-void SoundManager::unknownFunction4() {
- // TODO: Add mutex ?
- warning("Sound::unknownFunction4: not implemented!");
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Entry search
-//////////////////////////////////////////////////////////////////////////
-SoundManager::SoundEntry *SoundManager::getEntry(EntityIndex index) {
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- if ((*i)->entity == index)
- return *i;
- }
-
- return NULL;
-}
-
-SoundManager::SoundEntry *SoundManager::getEntry(Common::String name) {
- if (!name.contains('.'))
- name += ".SND";
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- if ((*i)->name2 == name)
- return *i;
- }
-
- return NULL;
-}
-
-SoundManager::SoundEntry *SoundManager::getEntry(SoundType type) {
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- if ((*i)->type == type)
- return *i;
- }
-
- return NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Savegame
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::saveLoadWithSerializer(Common::Serializer &s) {
- s.syncAsUint32LE(_state);
- s.syncAsUint32LE(_currentType);
-
- // Compute the number of entries to save
- uint32 numEntries = count();
- s.syncAsUint32LE(numEntries);
-
- Common::StackLock locker(_mutex);
-
- // Save or load each entry data
- if (s.isSaving()) {
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
- SoundEntry *entry = *i;
- if (entry->name2.matchString("NISSND?") && (entry->status.status & kFlagType7) != kFlag3) {
- s.syncAsUint32LE(entry->status.status); // status;
- s.syncAsUint32LE(entry->type); // type;
- s.syncAsUint32LE(entry->field_1C); // field_8;
- s.syncAsUint32LE(entry->time); // time;
- s.syncAsUint32LE(entry->field_34); // field_10;
- s.syncAsUint32LE(entry->field_38); // field_14;
- s.syncAsUint32LE(entry->entity); // entity;
-
- uint32 field_1C = (uint32)entry->field_48 - _data2;
- if (field_1C > kFlag8)
- field_1C = 0;
- s.syncAsUint32LE(field_1C); // field_1C;
-
- s.syncAsUint32LE(entry->field_4C); // field_20;
-
- char name1[16];
- strcpy((char *)&name1, entry->name1.c_str());
- s.syncBytes((byte *)&name1, 16);
-
- char name2[16];
- strcpy((char *)&name2, entry->name2.c_str());
- s.syncBytes((byte *)&name2, 16);
- }
- }
- } else {
- warning("Sound::saveLoadWithSerializer: not implemented!");
- s.skip(numEntries * 64);
- }
-}
-
-
-// FIXME: We probably need another mutex here to protect during the whole savegame process
-// as we could have removed an entry between the time we check the count and the time we
-// save the entries
-uint32 SoundManager::count() {
- Common::StackLock locker(_mutex);
-
- uint32 numEntries = 0;
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
- if ((*i)->name2.matchString("NISSND?"))
- ++numEntries;
-
- return numEntries;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Game-related functions
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::playSound(EntityIndex entity, Common::String filename, FlagType flag, byte a4) {
- if (isBuffered(entity) && entity)
- removeFromQueue(entity);
-
- FlagType currentFlag = (flag == -1) ? getSoundFlag(entity) : (FlagType)(flag | 0x80000);
-
- // Add .SND at the end of the filename if needed
- if (!filename.contains('.'))
- filename += ".SND";
-
- if (!playSoundWithSubtitles(filename, currentFlag, entity, a4))
- if (entity)
- getSavePoints()->push(kEntityPlayer, entity, kActionEndSound);
-}
-
-bool SoundManager::playSoundWithSubtitles(Common::String filename, FlagType flag, EntityIndex entity, byte a4) {
- SoundEntry *entry = new SoundEntry();
-
- Common::StackLock locker(_mutex);
-
- setupEntry(entry, filename, flag, 30);
- entry->entity = entity;
-
- if (a4) {
- entry->field_48 = _data2 + 2 * a4;
- entry->status.status |= kSoundStatus_8000;
- } else {
- // Get subtitles name
- while (filename.size() > 4)
- filename.deleteLastChar();
-
- showSubtitle(entry, filename);
- updateEntryState(entry);
- }
-
- return (entry->type != kSoundTypeNone);
-}
-
-void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
- int values[5];
-
- if (getEntityData(entity)->car != getEntityData(kEntityPlayer)->car)
- return;
-
- if (getEntities()->isInSalon(entity) != getEntities()->isInSalon(kEntityPlayer))
- return;
-
- int _action = (int)action;
- FlagType flag = getSoundFlag(entity);
-
- switch (action) {
- case 36: {
- int _param3 = (flag <= 9) ? flag + 7 : 16;
-
- if (_param3 > 7) {
- _data0 = (uint)_param3;
- _data1 = _data2 + 2 * a3;
- }
- break;
- }
-
- case 37:
- _data0 = 7;
- _data1 = _data2 + 2 * a3;
- break;
-
- case 150:
- case 156:
- case 162:
- case 168:
- case 188:
- case 198:
- _action += 1 + (int)rnd(5);
- break;
-
- case 174:
- case 184:
- case 194:
- _action += 1 + (int)rnd(3);
- break;
-
- case 180:
- _action += 1 + (int)rnd(4);
- break;
-
- case 246:
- values[0] = 0;
- values[1] = 104;
- values[2] = 105;
- values[3] = 106;
- values[4] = 116;
- _action = values[rnd(5)];
- break;
-
- case 247:
- values[0] = 11;
- values[1] = 123;
- values[2] = 124;
- _action = values[rnd(3)];
- break;
-
- case 248:
- values[0] = 0;
- values[1] = 103;
- values[2] = 108;
- values[3] = 109;
- _action = values[rnd(4)];
- break;
-
- case 249:
- values[0] = 0;
- values[1] = 56;
- values[2] = 112;
- values[3] = 113;
- _action = values[rnd(4)];
- break;
-
- case 250:
- values[0] = 0;
- values[1] = 107;
- values[2] = 115;
- values[3] = 117;
- _action = values[rnd(4)];
- break;
-
- case 251:
- values[0] = 0;
- values[1] = 11;
- values[2] = 56;
- values[3] = 113;
- _action = values[rnd(4)];
- break;
-
- case 252:
- values[0] = 0;
- values[1] = 6;
- values[2] = 109;
- values[3] = 121;
- _action = values[rnd(4)];
- break;
-
- case 254:
- values[0] = 0;
- values[1] = 104;
- values[2] = 120;
- values[3] = 121;
- _action = values[rnd(4)];
- break;
-
- case 255:
- values[0] = 0;
- values[1] = 106;
- values[2] = 115;
- _action = values[rnd(3)];
- break;
-
- default:
- break;
- }
-
- if (_action && flag)
- playSoundWithSubtitles(Common::String::format("LIB%03d.SND", _action), flag, kEntityPlayer, a3);
-}
-
-void SoundManager::playSteam(CityIndex index) {
- if (index >= ARRAYSIZE(cities))
- error("SoundManager::playSteam: invalid city index (was %d, max %d)", index, ARRAYSIZE(cities));
-
- _state |= kSoundState2;
-
- if (!getEntry(kSoundType1))
- playSoundWithSubtitles("STEAM.SND", kFlagSteam, kEntitySteam);
-
- // Get the new sound entry and show subtitles
- SoundEntry *entry = getEntry(kSoundType1);
- if (entry)
- showSubtitle(entry, cities[index]);
-}
-
-void SoundManager::playFightSound(byte action, byte a4) {
- int _action = (int)action;
- int values[5];
-
- switch (action) {
- default:
- break;
-
- case 174:
- case 184:
- case 194:
- values[0] = action + 1;
- values[1] = action + 2;
- values[2] = action + 3;
- _action = values[rnd(3)];
- break;
-
- case 180:
- values[0] = action + 1;
- values[1] = action + 2;
- values[2] = action + 3;
- values[3] = action + 4;
- _action = values[rnd(4)];
- break;
-
- case 150:
- case 156:
- case 162:
- case 168:
- case 188:
- case 198:
- values[0] = action + 1;
- values[1] = action + 2;
- values[2] = action + 3;
- values[3] = action + 4;
- values[4] = action + 5;
- _action = values[rnd(5)];
- break;
- }
-
- if (_action)
- playSound(kEntityTrain, Common::String::format("LIB%03d.SND", _action), kFlagDefault, a4);
-}
-
-void SoundManager::playDialog(EntityIndex entity, EntityIndex entityDialog, FlagType flag, byte a4) {
- if (isBuffered(getDialogName(entityDialog)))
- removeFromQueue(getDialogName(entityDialog));
-
- playSound(entity, getDialogName(entityDialog), flag, a4);
-}
-
-void SoundManager::playLocomotiveSound() {
- playSound(kEntityPlayer, locomotiveSounds[rnd(5)], (FlagType)(rnd(15) + 2));
-}
-
-const char *SoundManager::getDialogName(EntityIndex entity) const {
- switch (entity) {
- case kEntityAnna:
- if (getEvent(kEventAnnaDialogGoToJerusalem))
- return "XANN12";
-
- if (getEvent(kEventLocomotiveRestartTrain))
- return "XANN11";
-
- if (getEvent(kEventAnnaBaggageTies) || getEvent(kEventAnnaBaggageTies2) || getEvent(kEventAnnaBaggageTies3) || getEvent(kEventAnnaBaggageTies4))
- return "XANN10";
-
- if (getEvent(kEventAnnaTired) || getEvent(kEventAnnaTiredKiss))
- return "XANN9";
-
- if (getEvent(kEventAnnaBaggageArgument))
- return "XANN8";
-
- if (getEvent(kEventKronosVisit))
- return "XANN7";
-
- if (getEvent(kEventAbbotIntroduction))
- return "XANN6A";
-
- if (getEvent(kEventVassiliSeizure))
- return "XANN6";
-
- if (getEvent(kEventAugustPresentAnna) || getEvent(kEventAugustPresentAnnaFirstIntroduction))
- return "XANN5";
-
- if (getProgress().field_60)
- return "XANN4";
-
- if (getEvent(kEventAnnaGiveScarf) || getEvent(kEventAnnaGiveScarfDiner) || getEvent(kEventAnnaGiveScarfSalon)
- || getEvent(kEventAnnaGiveScarfMonogram) || getEvent(kEventAnnaGiveScarfDinerMonogram) || getEvent(kEventAnnaGiveScarfSalonMonogram))
- return "XANN3";
-
- if (getEvent(kEventDinerMindJoin))
- return "XANN2";
-
- if (getEvent(kEventGotALight) || getEvent(kEventGotALightD))
- return "XANN1";
-
- break;
-
- case kEntityAugust:
- if (getEvent(kEventAugustTalkCigar))
- return "XAUG6";
-
- if (getEvent(kEventAugustBringBriefcase))
- return "XAUG5";
-
- // Getting closer to Vienna...
- if (getState()->time > kTime2200500 && !getEvent(kEventAugustMerchandise))
- return "XAUG4A";
-
- if (getEvent(kEventAugustMerchandise))
- return "XAUG4";
-
- if (getEvent(kEventDinerAugust) || getEvent(kEventDinerAugustAlexeiBackground) || getEvent(kEventMeetAugustTylerCompartment)
- || getEvent(kEventMeetAugustTylerCompartmentBed) || getEvent(kEventMeetAugustHisCompartment) || getEvent(kEventMeetAugustHisCompartmentBed))
- return "XAUG3";
-
- if (getEvent(kEventAugustPresentAnnaFirstIntroduction))
- return "XAUG2";
-
- if (getProgress().eventMertensAugustWaiting)
- return "XAUG1";
-
- break;
-
- case kEntityTatiana:
- if (getEvent(kEventTatianaTylerCompartment))
- return "XTAT6";
-
- if (getEvent(kEventTatianaCompartmentStealEgg))
- return "XTAT5";
-
- if (getEvent(kEventTatianaGivePoem))
- return "XTAT3";
-
- if (getProgress().field_64)
- return "XTAT1";
-
- break;
-
- case kEntityVassili:
- if (getEvent(kEventCathFreePassengers))
- return "XVAS4";
-
- if (getEvent(kEventVassiliCompartmentStealEgg))
- return "XVAS3";
-
- if (getEvent(kEventAbbotIntroduction))
- return "XVAS2";
-
- if (getEvent(kEventVassiliSeizure))
- return "XVAS1A";
-
- if (getProgress().field_64)
- return "XVAS1";
-
- break;
-
- case kEntityAlexei:
- if (getProgress().field_88)
- return "XALX6";
-
- if (getProgress().field_8C)
- return "XALX5";
-
- if (getProgress().field_90)
- return "XALX4A";
-
- if (getProgress().field_68)
- return "XALX4";
-
- if (getEvent(kEventAlexeiSalonPoem))
- return "XALX3";
-
- if (getEvent(kEventAlexeiSalonVassili))
- return "XALX2";
-
- if (getEvent(kEventAlexeiDiner) || getEvent(kEventAlexeiDinerOriginalJacket))
- return "XALX1";
-
- break;
-
- case kEntityAbbot:
- if (getEvent(kEventAbbotDrinkDefuse))
- return "XABB4";
-
- if (getEvent(kEventAbbotInvitationDrink) || getEvent(kEventDefuseBomb))
- return "XABB3";
-
- if (getEvent(kEventAbbotWrongCompartment) || getEvent(kEventAbbotWrongCompartmentBed))
- return "XABB2";
-
- if (getEvent(kEventAbbotIntroduction))
- return "XABB1";
-
- break;
-
- case kEntityMilos:
- if (getEvent(kEventLocomotiveMilosDay) || getEvent(kEventLocomotiveMilosNight))
- return "XMIL5";
-
- if (getEvent(kEventMilosCompartmentVisitTyler) && (getProgress().chapter == kChapter3 || getProgress().chapter == kChapter4))
- return "XMIL4";
-
- if (getEvent(kEventMilosCorridorThanks) || getProgress().chapter == kChapter5)
- return "XMIL3";
-
- if (getEvent(kEventMilosCompartmentVisitAugust))
- return "XMIL2";
-
- if (getEvent(kEventMilosTylerCompartmentDefeat))
- return "XMIL1";
-
- break;
-
- case kEntityVesna:
- if (getProgress().field_94)
- return "XVES2";
-
- if (getProgress().field_98)
- return "XVES1";
-
- break;
-
- case kEntityKronos:
- if (getEvent(kEventKronosReturnBriefcase))
- return "XKRO6";
-
- if (getEvent(kEventKronosBringEggCeiling) || getEvent(kEventKronosBringEgg))
- return "XKRO5";
-
- if (getEvent(kEventKronosConversation) || getEvent(kEventKronosConversationFirebird)) {
- ObjectLocation location = getInventory()->get(kItemFirebird)->location;
- if (location != kObjectLocation6 && location != kObjectLocation5 && location != kObjectLocation2 && location != kObjectLocation1)
- return "XKRO4A";
- }
-
- if (getEvent(kEventKronosConversationFirebird))
- return "XKRO4";
-
- if (getEvent(kEventKronosConversation)) {
- if (!getEvent(kEventMilosCompartmentVisitAugust))
- return "XKRO3";
- else
- return "XKRO2";
- }
-
- if (getProgress().eventMertensKronosInvitation)
- return "XKRO1";
-
- break;
-
- case kEntityFrancois:
- if (getProgress().field_9C)
- return "XFRA3";
-
- if (getProgress().field_A0
- || getEvent(kEventFrancoisWhistle) || getEvent(kEventFrancoisWhistleD)
- || getEvent(kEventFrancoisWhistleNight) || getEvent(kEventFrancoisWhistleNightD))
- return "XFRA2";
-
- if (getState()->time > kTimeParisEpernay) // Between Paris and Epernay
- return "XFRA1";
-
- break;
-
- case kEntityMmeBoutarel:
- if (getProgress().field_A4)
- return "XMME4";
-
- if (getProgress().field_A8)
- return "XMME3";
-
- if (getProgress().field_A0)
- return "XMME2";
-
- if (getProgress().field_AC)
- return "XMME1";
-
- break;
-
- case kEntityBoutarel:
- if (getProgress().eventMetBoutarel)
- return "XMRB1";
-
- break;
-
- case kEntityRebecca:
- if (getProgress().field_B4)
- return "XREB1A";
-
- if (getProgress().field_B8)
- return "XREB1";
-
- break;
-
- case kEntitySophie:
- if (getProgress().field_B0)
- return "XSOP2";
-
- if (getProgress().field_BC)
- return "XSOP1B";
-
- if (getProgress().field_B4)
- return "XSOP1A";
-
- if (getProgress().field_B8)
- return "XSOP1";
-
- break;
-
- case kEntityMahmud:
- if (getProgress().field_C4)
- return "XMAH1";
-
- break;
-
- case kEntityYasmin:
- if (getProgress().eventMetYasmin)
- return "XHAR2";
-
- break;
-
- case kEntityHadija:
- if (getProgress().eventMetHadija)
- return "XHAR1";
-
- break;
-
- case kEntityAlouan:
- if (getProgress().field_DC)
- return "XHAR3";
-
- break;
-
- case kEntityGendarmes:
- if (getProgress().field_E0)
- return "XHAR4";
-
- break;
-
- case kEntityChapters:
- if (getEvent(kEventCathDream) || getEvent(kEventCathWakingUp))
- return "XTYL3";
-
- return "XTYL1";
-
- default:
- break;
- }
-
- return NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Letters & Messages
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::readText(int id){
- if (!isBuffered(kEntityTables4))
- return;
-
- if (id < 0 || (id > 8 && id < 50) || id > 64)
- error("Sound::readText - attempting to use invalid id. Valid values [1;8] - [50;64], was %d", id);
-
- // Get proper message file (names are stored in sequence in the array but id is [1;8] - [50;64])
- const char *text = messages[id <= 8 ? id : id - 41];
-
- // Check if file is in cache for id [1;8]
- if (id <= 8)
- if (isBuffered(text))
- removeFromQueue(text);
-
- playSound(kEntityTables4, text, kFlagDefault);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Sound bites
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compartment) {
-
-#define PLAY_WARNING(index, sound1, sound2, sound3, sound4, sound5, sound6) { \
- if (_lastWarning[index] + 450 >= getState()->timeTicks) { \
- if (rnd(2)) \
- playSound(kEntityMertens, sound1, kFlagDefault); \
- else \
- playSound(kEntityMertens, rnd(2) ? sound2 : sound3, kFlagDefault); \
- } else { \
- if (rnd(2)) \
- playSound(kEntityMertens, sound4, kFlagDefault); \
- else \
- playSound(kEntityMertens, rnd(2) ? sound5 : sound6, kFlagDefault); \
- } \
- _lastWarning[index] = getState()->timeTicks; \
-}
-
- if (entity != kEntityMertens && entity != kEntityCoudert)
- return;
-
- //////////////////////////////////////////////////////////////////////////
- // Mertens
- if (entity == kEntityMertens) {
-
- switch (compartment) {
- default:
- break;
-
- case kObjectCompartment2:
- PLAY_WARNING(0, "Con1502A", "Con1500B", "Con1500C", "Con1502", "Con1500", "Con1500A");
- break;
-
- case kObjectCompartment3:
- PLAY_WARNING(1, "Con1501A", "Con1500B", "Con1500C", "Con1501", "Con1500", "Con1500A");
- break;
-
- case kObjectCompartment4:
- PLAY_WARNING(2, "Con1503", "Con1500B", "Con1500C", "Con1503", "Con1500", "Con1500A");
- break;
-
- case kObjectCompartment5:
- case kObjectCompartment6:
- case kObjectCompartment7:
- case kObjectCompartment8:
- ++_lastWarning[3];
-
- switch (_lastWarning[3]) {
- default:
- break;
-
- case 1:
- getSound()->playSound(kEntityMertens, "Con1503C", kFlagDefault);
- break;
-
- case 2:
- getSound()->playSound(kEntityMertens, rnd(2) ? "Con1503E" : "Con1503A", kFlagDefault);
- break;
-
- case 3:
- getSound()->playSound(kEntityMertens, rnd(2) ? "Con1503B" : "Con1503D", kFlagDefault);
- _lastWarning[3] = 0;
- break;
- }
- }
-
- return;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Coudert
- switch (compartment) {
- default:
- break;
-
- case kObjectCompartmentA:
- if (_lastWarning[4] + 450 >= getState()->timeTicks) {
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
- break;
- }
-
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1508" : "Jac1508A", kFlagDefault);
- break;
-
- case kObjectCompartmentB:
- if (_lastWarning[5] + 450 >= getState()->timeTicks) {
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
- break;
- }
-
- if (getProgress().field_40 || (getState()->time > kTimeCityLinz && getState()->time < kTime2133000))
- getSound()->playSound(kEntityCoudert, "Jac1507A", kFlagDefault);
- else
- getSound()->playSound(kEntityCoudert, "Jac1507", kFlagDefault);
- break;
-
- case kObjectCompartmentC:
- if (_lastWarning[6] + 450 >= getState()->timeTicks) {
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
- break;
- }
-
- if (getProgress().chapter < kChapter3)
- getSound()->playSound(kEntityCoudert, "Jac1506", kFlagDefault);
- else
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1506A" : "Jac1506B", kFlagDefault);
- break;
-
- case kObjectCompartmentD:
- if (_lastWarning[7] + 450 >= getState()->timeTicks) {
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
- break;
- }
-
- getSound()->playSound(kEntityCoudert, "Jac1505", kFlagDefault);
- break;
-
- case kObjectCompartmentE:
- if (_lastWarning[8] + 450 >= getState()->timeTicks) {
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
- break;
- }
-
- if (getProgress().field_40 || (getState()->time > kTime2115000 && getState()->time < kTime2133000)) {
- getSound()->playSound(kEntityCoudert, "Jac1504B", kFlagDefault);
- break;
- }
-
- if (getEntities()->isInsideCompartment(kEntityRebecca, kCarRedSleeping, kPosition_4840))
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
- else
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1504" : "Jac1504A", kFlagDefault);
- break;
-
- case kObjectCompartmentF:
- if (_lastWarning[9] + 450 >= getState()->timeTicks) {
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
- break;
- }
-
- if (getProgress().field_40 || (getState()->time > kTime2083500 && getState()->time < kTime2133000)) {
- getSound()->playSound(kEntityCoudert, "Jac1503B", kFlagDefault);
- break;
- }
-
- if (rnd(2) || getEntities()->isInsideCompartment(kEntityAnna, kCarRedSleeping, kPosition_4070))
- getSound()->playSound(kEntityCoudert, "Jac1503", kFlagDefault);
- else
- getSound()->playSound(kEntityCoudert, "Jac1503A", kFlagDefault);
- break;
-
- case kObjectCompartmentG:
- if (_lastWarning[10] + 450 >= getState()->timeTicks) {
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
- break;
- }
-
- if (rnd(2) || getEntities()->isInsideCompartment(kEntityMilos, kCarRedSleeping, kPosition_3050))
- getSound()->playSound(kEntityCoudert, "Jac1502", kFlagDefault);
- else
- getSound()->playSound(kEntityCoudert, "Jac1502A", kFlagDefault);
- break;
-
- case kObjectCompartmentH:
- if (_lastWarning[11] + 450 >= getState()->timeTicks) {
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
- break;
- }
-
- if (getEntities()->isInsideCompartment(kEntityIvo, kCarRedSleeping, kPosition_2740))
- getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
- else
- getSound()->playSound(kEntityCoudert, "Jac1501", kFlagDefault);
- break;
- }
-
- // Update ticks (Compartments A - H are indexes 4 - 11)
- _lastWarning[compartment - 28] = getState()->timeTicks;
-}
-
-void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, FlagType flag) {
- if (isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain)
- return;
-
- if (entity2 == kEntityFrancois || entity2 == kEntityMax)
- return;
-
- if (entity == kEntityFrancois && getEntityData(kEntityFrancois)->field_4A3 != 30)
- return;
-
- if (flag == kFlagNone)
- flag = getSoundFlag(entity);
-
- switch (entity) {
- default:
- break;
-
- case kEntityAnna:
- playSound(kEntityPlayer, "ANN1107A", flag);
- break;
-
- case kEntityAugust:
- switch(rnd(4)) {
- default:
- break;
-
- case 0:
- playSound(kEntityPlayer, "AUG1100A", flag);
- break;
-
- case 1:
- playSound(kEntityPlayer, "AUG1100B", flag);
- break;
-
- case 2:
- playSound(kEntityPlayer, "AUG1100C", flag);
- break;
-
- case 3:
- playSound(kEntityPlayer, "AUG1100D", flag);
- break;
- }
- break;
-
- case kEntityMertens:
- if (Entities::isFemale(entity2)) {
- playSound(kEntityPlayer, (rnd(2) ? "CON1111" : "CON1111A"), flag);
- } else {
- if (entity2 || getProgress().jacket != kJacketGreen || !rnd(2)) {
- switch(rnd(3)) {
- default:
- break;
-
- case 0:
- playSound(kEntityPlayer, "CON1110A", flag);
- break;
-
- case 1:
- playSound(kEntityPlayer, "CON1110C", flag);
- break;
-
- case 2:
- playSound(kEntityPlayer, "CON1110", flag);
- break;
- }
- } else {
- if (isNight()) {
- playSound(kEntityPlayer, (getProgress().field_18 == 2 ? "CON1110F" : "CON1110E"));
- } else {
- playSound(kEntityPlayer, "CON1110D");
- }
- }
- }
- break;
-
- case kEntityCoudert:
- if (Entities::isFemale(entity2)) {
- playSound(kEntityPlayer, "JAC1111D", flag);
- } else {
- if (entity2 || getProgress().jacket != kJacketGreen || !rnd(2)) {
- switch(rnd(4)) {
- default:
- break;
-
- case 0:
- playSound(kEntityPlayer, "JAC1111", flag);
- break;
-
- case 1:
- playSound(kEntityPlayer, "JAC1111A", flag);
- break;
-
- case 2:
- playSound(kEntityPlayer, "JAC1111B", flag);
- break;
-
- case 3:
- playSound(kEntityPlayer, "JAC1111C", flag);
- break;
- }
- } else {
- playSound(kEntityPlayer, "JAC1113B", flag);
- }
- }
- break;
-
- case kEntityPascale:
- playSound(kEntityPlayer, (rnd(2) ? "HDE1002" : "HED1002A"), flag);
- break;
-
- case kEntityServers0:
- case kEntityServers1:
- switch(rnd(3)) {
- default:
- break;
-
- case 0:
- playSound(kEntityPlayer, (entity == kEntityServers0) ? "WAT1002" : "WAT1003", flag);
- break;
-
- case 1:
- playSound(kEntityPlayer, (entity == kEntityServers0) ? "WAT1002A" : "WAT1003A", flag);
- break;
-
- case 2:
- playSound(kEntityPlayer, (entity == kEntityServers0) ? "WAT1002B" : "WAT1003B", flag);
- break;
- }
- break;
-
- case kEntityVerges:
- if (Entities::isFemale(entity2)) {
- playSound(kEntityPlayer, (rnd(2) ? "TRA1113A" : "TRA1113B"));
- } else {
- playSound(kEntityPlayer, "TRA1112", flag);
- }
- break;
-
- case kEntityTatiana:
- playSound(kEntityPlayer, (rnd(2) ? "TAT1102A" : "TAT1102B"), flag);
- break;
-
- case kEntityAlexei:
- playSound(kEntityPlayer, (rnd(2) ? "ALX1099C" : "ALX1099D"), flag);
- break;
-
- case kEntityAbbot:
- if (Entities::isFemale(entity2)) {
- playSound(kEntityPlayer, "ABB3002C", flag);
- } else {
- switch(rnd(3)) {
- default:
- break;
-
- case 0:
- playSound(kEntityPlayer, "ABB3002", flag);
- break;
-
- case 1:
- playSound(kEntityPlayer, "ABB3002A", flag);
- break;
-
- case 2:
- playSound(kEntityPlayer, "ABB3002B", flag);
- break;
- }
- }
- break;
-
- case kEntityVesna:
- switch(rnd(3)) {
- default:
- break;
-
- case 0:
- playSound(kEntityPlayer, "VES1109A", flag);
- break;
-
- case 1:
- playSound(kEntityPlayer, "VES1109B", flag);
- break;
-
- case 2:
- playSound(kEntityPlayer, "VES1109C", flag);
- break;
- }
- break;
-
- case kEntityKahina:
- playSound(kEntityPlayer, (rnd(2) ? "KAH1001" : "KAH1001A"), flag);
- break;
-
- case kEntityFrancois:
- case kEntityMmeBoutarel:
- switch(rnd(4)) {
- default:
- break;
-
- case 0:
- playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001" : "MME1103A", flag);
- break;
-
- case 1:
- playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001A" : "MME1103B", flag);
- break;
-
- case 2:
- playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001B" : "MME1103C", flag);
- break;
-
- case 3:
- playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001C" : "MME1103D", flag);
- break;
- }
- break;
-
- case kEntityBoutarel:
- playSound(kEntityPlayer, "MRB1104", flag);
- if (flag > 2)
- getProgress().eventMetBoutarel = true;
- break;
-
- case kEntityRebecca:
- playSound(kEntityPlayer, (rnd(2) ? "REB1106" : "REB110A"), flag);
- break;
-
- case kEntitySophie: {
- switch(rnd(3)) {
- default:
- break;
-
- case 0:
- playSound(kEntityPlayer, "SOP1105", flag);
- break;
-
- case 1:
- playSound(kEntityPlayer, Entities::isFemale(entity2) ? "SOP1105C" : "SOP1105A", flag);
- break;
-
- case 2:
- playSound(kEntityPlayer, Entities::isFemale(entity2) ? "SOP1105D" : "SOP1105B", flag);
- break;
- }
- break;
- }
-
- case kEntityMahmud:
- playSound(kEntityPlayer, "MAH1101", flag);
- break;
-
- case kEntityYasmin:
- playSound(kEntityPlayer, "HAR1002", flag);
- if (flag > 2)
- getProgress().eventMetYasmin = true;
- break;
-
- case kEntityHadija:
- playSound(kEntityPlayer, (rnd(2) ? "HAR1001" : "HAR1001A"), flag);
- if (flag > 2)
- getProgress().eventMetHadija = true;
- break;
-
- case kEntityAlouan:
- playSound(kEntityPlayer, "HAR1004", flag);
- break;
- }
-}
-
-void SoundManager::excuseMeCath() {
- switch(rnd(3)) {
- default:
- playSound(kEntityPlayer, "CAT1126B");
- break;
-
- case 1:
- playSound(kEntityPlayer, "CAT1126C");
- break;
-
- case 2:
- playSound(kEntityPlayer, "CAT1126D");
- break;
- }
-}
-
-const char *SoundManager::justCheckingCath() const {
- switch(rnd(4)) {
- default:
- break;
-
- case 0:
- return "CAT5001";
-
- case 1:
- return "CAT5001A";
-
- case 2:
- return "CAT5001B";
-
- case 3:
- return "CAT5001C";
- }
-
- return "CAT5001";
-}
-
-const char *SoundManager::wrongDoorCath() const {
- switch(rnd(5)) {
- default:
- break;
-
- case 0:
- return "CAT1125";
-
- case 1:
- return "CAT1125A";
-
- case 2:
- return "CAT1125B";
-
- case 3:
- return "CAT1125C";
-
- case 4:
- return "CAT1125D";
- }
-
- return "CAT1125";
-}
-
-const char *SoundManager::justAMinuteCath() const {
- switch(rnd(3)) {
- default:
- break;
-
- case 0:
- return "CAT1520";
-
- case 1:
- return "CAT1521";
-
- case 2:
- return "CAT1125"; // ?? is this a bug in the original?
- }
-
- return "CAT1520";
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Sound flags
-//////////////////////////////////////////////////////////////////////////
-SoundManager::FlagType SoundManager::getSoundFlag(EntityIndex entity) const {
- if (entity == kEntityPlayer)
- return kFlagDefault;
-
- if (getEntityData(entity)->car != getEntityData(kEntityPlayer)->car)
- return kFlagNone;
-
- // Compute sound value
- FlagType ret = kFlag2;
-
- // Get default value if valid
- int index = ABS(getEntityData(entity)->entityPosition - getEntityData(kEntityPlayer)->entityPosition) / 230;
- if (index < 32)
- ret = soundFlags[index];
-
- if (getEntityData(entity)->location == kLocationOutsideTrain) {
- if (getEntityData(entity)->car != kCarKronos
- && !getEntities()->isOutsideAlexeiWindow()
- && !getEntities()->isOutsideAnnaWindow())
- return kFlagNone;
-
- return (FlagType)(ret / 6);
- }
-
- switch (getEntityData(entity)->car) {
- default:
- break;
-
- case kCarKronos:
- if (getEntities()->isInKronosSalon(entity) != getEntities()->isInKronosSalon(kEntityPlayer))
- ret = (FlagType)(ret * 2);
- break;
-
- case kCarGreenSleeping:
- case kCarRedSleeping:
- if (getEntities()->isInGreenCarEntrance(kEntityPlayer) && !getEntities()->isInKronosSalon(entity))
- ret = (FlagType)(ret * 2);
-
- if (getEntityData(kEntityPlayer)->location
- && (getEntityData(entity)->entityPosition != kPosition_1 || !getEntities()->isDistanceBetweenEntities(kEntityPlayer, entity, 400)))
- ret = (FlagType)(ret * 2);
- break;
-
- case kCarRestaurant:
- if (getEntities()->isInSalon(entity) == getEntities()->isInSalon(kEntityPlayer)
- && (getEntities()->isInRestaurant(entity) != getEntities()->isInRestaurant(kEntityPlayer)))
- ret = (FlagType)(ret * 2);
- else
- ret = (FlagType)(ret * 4);
- break;
- }
-
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Subtitles
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::updateSubtitles() {
- Common::StackLock locker(_mutex);
-
- uint32 index = 0;
- SubtitleEntry *subtitle = NULL;
-
- for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
- uint32 current_index = 0;
- SoundEntry *soundEntry = (*i)->sound;
- SoundStatus status = (SoundStatus)soundEntry->status.status;
-
- if (!(status & kSoundStatus_40)
- || status & 0x180
- || soundEntry->time == 0
- || (status & 0x1F) < 6
- || ((getFlags()->nis & 0x8000) && soundEntry->field_4C < 90)) {
- current_index = 0;
- } else {
- current_index = soundEntry->field_4C + (status & 0x1F);
-
- if (_currentSubtitle == (*i))
- current_index += 4;
- }
-
- if (index < current_index) {
- index = current_index;
- subtitle = (*i);
- }
- }
-
- if (_currentSubtitle == subtitle) {
- if (subtitle)
- setupSubtitleAndDraw(subtitle);
-
- return;
- }
-
- if (_drawSubtitles & 1)
- drawSubtitleOnScreen(subtitle);
-
- if (subtitle) {
- loadSubtitleData(subtitle);
- setupSubtitleAndDraw(subtitle);
- }
-}
-
-void SoundManager::showSubtitle(SoundEntry *entry, Common::String filename) {
- entry->subtitle = loadSubtitle(filename, entry);
-
- if (entry->subtitle->status.status2 & 4) {
- drawSubtitle(entry->subtitle);
- SAFE_DELETE(entry->subtitle);
- } else {
- entry->status.status |= kSoundStatus_20000;
- }
-}
-
-SoundManager::SubtitleEntry *SoundManager::loadSubtitle(Common::String filename, SoundEntry *soundEntry) {
- SubtitleEntry *entry = new SubtitleEntry();
- _subtitles.push_back(entry);
-
- // Set sound entry and filename
- entry->filename = filename + ".SBE";
- entry->sound = soundEntry;
-
- // Load subtitle data
- if (_engine->getResourceManager()->hasFile(filename)) {
- if (_drawSubtitles & 2)
- return entry;
-
- loadSubtitleData(entry);
- } else {
- entry->status.status = kSoundStatus_400;
- }
-
- return entry;
-}
-
-void SoundManager::loadSubtitleData(SubtitleEntry * entry) {
- entry->data = new SubtitleManager(_engine->getFont());
- entry->data->load(getArchive(entry->filename));
-
- _drawSubtitles |= 2;
- _currentSubtitle = entry;
-}
-
-void SoundManager::setupSubtitleAndDraw(SubtitleEntry *subtitle) {
- if (!subtitle->data) {
- subtitle->data = new SubtitleManager(_engine->getFont());
- subtitle->data->load(getArchive(subtitle->filename));
- }
-
- if (subtitle->data->getMaxTime() > subtitle->sound->time) {
- subtitle->status.status = kSoundStatus_400;
- } else {
- subtitle->data->setTime((uint16)subtitle->sound->time);
-
- if (_drawSubtitles & 1)
- drawSubtitleOnScreen(subtitle);
- }
-
- _currentSubtitle = subtitle;
-}
-
-void SoundManager::drawSubtitle(SubtitleEntry *subtitle) {
- // Remove subtitle from queue
- _subtitles.remove(subtitle);
-
- if (subtitle == _currentSubtitle) {
- drawSubtitleOnScreen(subtitle);
-
- _currentSubtitle = NULL;
- _drawSubtitles = 0;
- }
-}
-
-void SoundManager::drawSubtitleOnScreen(SubtitleEntry *subtitle) {
- if (!subtitle)
- error("SoundManager::drawSubtitleOnScreen: Invalid subtitle entry!");
-
- _drawSubtitles &= ~1;
-
- if (subtitle->data == NULL)
- return;
-
- if (_drawSubtitles & 1)
- _engine->getGraphicsManager()->draw(subtitle->data, GraphicsManager::kBackgroundOverlay);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Misc
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::playLoopingSound() {
- warning("SoundManager::playLoopingSound: not implemented!");
-}
-
-void SoundManager::stopAllSound() {
- Common::StackLock locker(_mutex);
-
- for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
- (*i)->soundStream->stop();
-}
-
-} // End of namespace LastExpress