diff options
Diffstat (limited to 'engines/lastexpress/game')
-rw-r--r-- | engines/lastexpress/game/action.cpp | 48 | ||||
-rw-r--r-- | engines/lastexpress/game/entities.cpp | 8 | ||||
-rw-r--r-- | engines/lastexpress/game/inventory.cpp | 8 | ||||
-rw-r--r-- | engines/lastexpress/game/logic.cpp | 16 | ||||
-rw-r--r-- | engines/lastexpress/game/savegame.cpp | 10 | ||||
-rw-r--r-- | engines/lastexpress/game/scenes.cpp | 12 | ||||
-rw-r--r-- | engines/lastexpress/game/sound.cpp | 803 | ||||
-rw-r--r-- | engines/lastexpress/game/sound.h | 119 |
8 files changed, 100 insertions, 924 deletions
diff --git a/engines/lastexpress/game/action.cpp b/engines/lastexpress/game/action.cpp index 54bb8759ee..f195825d6e 100644 --- a/engines/lastexpress/game/action.cpp +++ b/engines/lastexpress/game/action.cpp @@ -42,6 +42,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" #include "lastexpress/resource.h" @@ -453,7 +455,7 @@ IMPLEMENT_ACTION(savePoint) IMPLEMENT_ACTION(playSound) // Check that the file is not already buffered - if (hotspot.param2 || !getSound()->isBuffered(Common::String::format("LIB%03d", hotspot.param1), true)) + if (hotspot.param2 || !getSoundQueue()->isBuffered(Common::String::format("LIB%03d", hotspot.param1), true)) getSound()->playSoundEvent(kEntityPlayer, hotspot.param1, hotspot.param2); return kSceneInvalid; @@ -465,7 +467,7 @@ IMPLEMENT_ACTION(playMusic) // Check that the file is not already buffered Common::String filename = Common::String::format("MUS%03d", hotspot.param1); - if (!getSound()->isBuffered(filename) && (hotspot.param1 != 50 || getProgress().chapter == kChapter5)) + if (!getSoundQueue()->isBuffered(filename) && (hotspot.param1 != 50 || getProgress().chapter == kChapter5)) getSound()->playSound(kEntityPlayer, filename, kFlagDefault, hotspot.param2); return kSceneInvalid; @@ -481,7 +483,7 @@ IMPLEMENT_ACTION(knock) if (getObjects()->get(object).entity) { getSavePoints()->push(kEntityPlayer, getObjects()->get(object).entity, kActionKnock, object); } else { - if (!getSound()->isBuffered("LIB012", true)) + if (!getSoundQueue()->isBuffered("LIB012", true)) getSound()->playSoundEvent(kEntityPlayer, 12); } @@ -516,7 +518,7 @@ IMPLEMENT_ACTION(compartment) && (compartment != kObjectCompartment1 || !getInventory()->hasItem(kItemKey) || (getInventory()->getSelectedItem() != kItemFirebird && getInventory()->getSelectedItem() != kItemBriefcase)))) { - if (!getSound()->isBuffered("LIB13")) + if (!getSoundQueue()->isBuffered("LIB13")) getSound()->playSoundEvent(kEntityPlayer, 13); // Stop processing further @@ -621,7 +623,7 @@ IMPLEMENT_ACTION(updateObjetLocation2) getObjects()->updateLocation2(object, location); - if (object != kObject112 || getSound()->isBuffered("LIB096")) { + if (object != kObject112 || getSoundQueue()->isBuffered("LIB096")) { if (object == 1) getSound()->playSoundEvent(kEntityPlayer, 73); } else { @@ -805,7 +807,7 @@ IMPLEMENT_ACTION(enterCompartment) getSound()->playSoundEvent(kEntityPlayer, 14); getSound()->playSoundEvent(kEntityPlayer, 15, 22); - if (getProgress().field_78 && !getSound()->isBuffered("MUS003")) { + if (getProgress().field_78 && !getSoundQueue()->isBuffered("MUS003")) { getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault); getProgress().field_78 = 0; } @@ -1083,7 +1085,7 @@ IMPLEMENT_ACTION(25) break; case 2: - if (!getSound()->isBuffered("MUS021")) + if (!getSoundQueue()->isBuffered("MUS021")) getSound()->playSound(kEntityPlayer, "MUS021", kFlagDefault); break; @@ -1134,7 +1136,7 @@ IMPLEMENT_ACTION(26) ////////////////////////////////////////////////////////////////////////// // Action 27 IMPLEMENT_ACTION(27) - if (!getSound()->isBuffered("LIB031", true)) + if (!getSoundQueue()->isBuffered("LIB031", true)) getSound()->playSoundEvent(kEntityPlayer, 31); switch (getEntityData(kEntityPlayer)->car) { @@ -1182,7 +1184,7 @@ IMPLEMENT_ACTION(29) getSound()->playSoundEvent(kEntityPlayer, hotspot.param1, hotspot.param2); Common::String filename = Common::String::format("MUS%03d", hotspot.param3); - if (!getSound()->isBuffered(filename)) + if (!getSoundQueue()->isBuffered(filename)) getSound()->playSound(kEntityPlayer, filename, kFlagDefault); return kSceneInvalid; @@ -1354,7 +1356,7 @@ IMPLEMENT_ACTION(dialog) // Action 38 IMPLEMENT_ACTION(eggBox) getSound()->playSoundEvent(kEntityPlayer, 43); - if (getProgress().field_7C && !getSound()->isBuffered("MUS003")) { + if (getProgress().field_7C && !getSoundQueue()->isBuffered("MUS003")) { getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault); getProgress().field_7C = 0; } @@ -1366,7 +1368,7 @@ IMPLEMENT_ACTION(eggBox) // Action 39 IMPLEMENT_ACTION(39) getSound()->playSoundEvent(kEntityPlayer, 24); - if (getProgress().field_80 && !getSound()->isBuffered("MUS003")) { + if (getProgress().field_80 && !getSoundQueue()->isBuffered("MUS003")) { getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault); getProgress().field_80 = 0; } @@ -1408,7 +1410,7 @@ IMPLEMENT_ACTION(playMusicChapter) if (id) { Common::String filename = Common::String::format("MUS%03d", id); - if (!getSound()->isBuffered(filename)) + if (!getSoundQueue()->isBuffered(filename)) getSound()->playSound(kEntityPlayer, filename, kFlagDefault); } @@ -1440,7 +1442,7 @@ IMPLEMENT_ACTION(playMusicChapterSetupTrain) Common::String filename = Common::String::format("MUS%03d", hotspot.param1); - if (!getSound()->isBuffered(filename) && hotspot.param3 & id) { + if (!getSoundQueue()->isBuffered(filename) && hotspot.param3 & id) { getSound()->playSound(kEntityPlayer, filename, kFlagDefault); getSavePoints()->call(kEntityPlayer, kEntityTrain, kAction203863200, filename.c_str()); @@ -1612,7 +1614,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityMertens)) + if (!getSoundQueue()->isBuffered(kEntityMertens)) getSound()->playWarningCompartment(kEntityMertens, object); getSavePoints()->push(kEntityPlayer, kEntityMertens, kAction305159806); @@ -1628,7 +1630,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityMertens)) + if (!getSoundQueue()->isBuffered(kEntityMertens)) getSound()->playSound(kEntityMertens, (rnd(2)) ? "JAC1000" : "JAC1000A"); if (doLoadScene) @@ -1640,7 +1642,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityMertens)) + if (!getSoundQueue()->isBuffered(kEntityMertens)) getSound()->playSound(kEntityMertens, (rnd(2)) ? "JAC1000" : "JAC1000A"); if (doLoadScene) @@ -1667,7 +1669,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityCoudert)) + if (!getSoundQueue()->isBuffered(kEntityCoudert)) getSound()->playWarningCompartment(kEntityCoudert, object); getSavePoints()->push(kEntityPlayer, kEntityCoudert, kAction305159806); @@ -1684,7 +1686,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityCoudert)) + if (!getSoundQueue()->isBuffered(kEntityCoudert)) getSound()->playSound(kEntityCoudert, (rnd(2)) ? "JAC1000" : "JAC1000A"); if (doLoadScene) @@ -1699,7 +1701,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityCoudert)) + if (!getSoundQueue()->isBuffered(kEntityCoudert)) getSound()->playSound(kEntityCoudert, (rnd(2)) ? "JAC1000" : "JAC1000A"); if (doLoadScene) @@ -1930,8 +1932,8 @@ void Action::playAnimation(EventIndex index, bool debugMode) const { if (!getFlags()->mouseRightClick) { if (getGlobalTimer()) { - if (getSound()->isBuffered("TIMER")) { - getSound()->processEntry("TIMER"); + if (getSoundQueue()->isBuffered("TIMER")) { + getSoundQueue()->processEntry("TIMER"); setGlobalTimer(105); } } @@ -1948,8 +1950,8 @@ void Action::playAnimation(EventIndex index, bool debugMode) const { if (animation.load(getArchive(Common::String(_animationList[index].filename) + ".nis") , processSound ? Animation::kFlagDefault : Animation::kFlagProcess)) animation.play(); - if (getSound()->isBuffered("TIMER")) - getSound()->removeFromQueue("TIMER"); + if (getSoundQueue()->isBuffered("TIMER")) + getSoundQueue()->removeFromQueue("TIMER"); } // Show cursor diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp index 0fa3af36b7..8dd2c26c19 100644 --- a/engines/lastexpress/game/entities.cpp +++ b/engines/lastexpress/game/entities.cpp @@ -71,6 +71,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -299,7 +301,7 @@ void Entities::setupChapter(ChapterIndex chapter) { memset(&_compartments1, 0, sizeof(_compartments1)); memset(&_positions, 0, sizeof(_positions)); - getSound()->resetQueue(kSoundType13); + getSoundQueue()->resetQueue(kSoundType13); } // we skip the header when doing entity setup @@ -369,8 +371,8 @@ void Entities::resetState(EntityIndex entityIndex) { getData(entityIndex)->currentCall = 0; getData(entityIndex)->inventoryItem = kItemNone; - if (getSound()->isBuffered(entityIndex)) - getSound()->removeFromQueue(entityIndex); + if (getSoundQueue()->isBuffered(entityIndex)) + getSoundQueue()->removeFromQueue(entityIndex); clearSequences(entityIndex); diff --git a/engines/lastexpress/game/inventory.cpp b/engines/lastexpress/game/inventory.cpp index 4d75fcaca5..c3a10225e9 100644 --- a/engines/lastexpress/game/inventory.cpp +++ b/engines/lastexpress/game/inventory.cpp @@ -33,6 +33,8 @@ #include "lastexpress/menu/menu.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -162,8 +164,8 @@ void Inventory::handleMouseEvent(const Common::Event &ev) { } else if (ev.type == Common::EVENT_RBUTTONDOWN) { if (getGlobalTimer()) { - if (getSound()->isBuffered("TIMER")) - getSound()->removeFromQueue("TIMER"); + if (getSoundQueue()->isBuffered("TIMER")) + getSoundQueue()->removeFromQueue("TIMER"); setGlobalTimer(900); } @@ -630,7 +632,7 @@ void Inventory::drawBlinkingEgg() { // if (getGlobalTimer() + ticks >= 90) // getSound()->playSoundWithSubtitles("TIMER.SND", 50331664, kEntityPlayer); - // if (getSound()->isBuffered("TIMER")) + // if (getSoundQueue()->isBuffered("TIMER")) // setGlobalTimer(0); //} diff --git a/engines/lastexpress/game/logic.cpp b/engines/lastexpress/game/logic.cpp index c1237eefe9..cdde2a0e0a 100644 --- a/engines/lastexpress/game/logic.cpp +++ b/engines/lastexpress/game/logic.cpp @@ -47,6 +47,8 @@ #include "lastexpress/menu/menu.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -152,7 +154,7 @@ void Logic::eventMouse(const Common::Event &ev) { _engine->getCursor()->setStyle(getInventory()->get(kItemWhistle)->cursor); // Check if clicked - if (ev.type == Common::EVENT_LBUTTONUP && !getSound()->isBuffered("LIB045")) { + if (ev.type == Common::EVENT_LBUTTONUP && !getSoundQueue()->isBuffered("LIB045")) { getSound()->playSoundEvent(kEntityPlayer, 45); @@ -424,7 +426,7 @@ void Logic::resetState() { */ void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, bool showScene) const { - getSound()->processEntries(); + getSoundQueue()->processEntries(); getEntities()->reset(); getFlags()->isGameRunning = false; getSavePoints()->reset(); @@ -432,16 +434,16 @@ void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, boo if (showScene) { - getSound()->processEntry(kSoundType11); + getSoundQueue()->processEntry(kSoundType11); if (sceneIndex && !getFlags()->mouseRightClick) { getScenes()->loadScene(sceneIndex); - while (getSound()->isBuffered(kEntityTables4)) { + while (getSoundQueue()->isBuffered(kEntityTables4)) { if (getFlags()->mouseRightClick) break; - getSound()->updateQueue(); + getSoundQueue()->updateQueue(); } } } @@ -451,7 +453,7 @@ void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, boo } void Logic::switchChapter() const { - getSound()->clearStatus(); + getSoundQueue()->clearStatus(); switch(getState()->progress.chapter) { default: @@ -491,7 +493,7 @@ void Logic::switchChapter() const { } void Logic::playFinalSequence() const { - getSound()->processEntries(); + getSoundQueue()->processEntries(); _action->playAnimation(kEventFinalSequence); showCredits(); diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp index 594cd1276b..8dfc214913 100644 --- a/engines/lastexpress/game/savegame.cpp +++ b/engines/lastexpress/game/savegame.cpp @@ -30,6 +30,8 @@ #include "lastexpress/menu/menu.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/debug.h" #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -125,7 +127,7 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) { while (_savegame->pos() < _savegame->size() && !_savegame->eos() && !_savegame->err()) { // Update sound queue while we go through the savegame - getSound()->updateQueue(); + getSoundQueue()->updateQueue(); SavegameEntryHeader *entry = new SavegameEntryHeader(); entry->saveLoadWithSerializer(ser); @@ -217,7 +219,7 @@ void SaveLoad::loadGame(GameId id) { _gameTicksLastSavegame = getState()->timeTicks; if (header.keepIndex) { - getSound()->clearQueue(); + getSoundQueue()->clearQueue(); readEntry(&type, &entity, &val, false); } @@ -377,7 +379,7 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) { WRITE_ENTRY("inventory", getInventory()->saveLoadWithSerializer(ser), 7 * 32); WRITE_ENTRY("objects", getObjects()->saveLoadWithSerializer(ser), 5 * 128); WRITE_ENTRY("entities", getEntities()->saveLoadWithSerializer(ser), 1262 * 40); - WRITE_ENTRY("sound", getSound()->saveLoadWithSerializer(ser), 3 * 4 + getSound()->count() * 64); + WRITE_ENTRY("sound", getSoundQueue()->saveLoadWithSerializer(ser), 3 * 4 + getSoundQueue()->count() * 64); WRITE_ENTRY("savepoints", getSavePoints()->saveLoadWithSerializer(ser), 128 * 16 + 4 + getSavePoints()->count() * 16); header.offset = (uint32)_savegame->pos() - (originalPosition + 32); @@ -452,7 +454,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b LOAD_ENTRY("inventory", getInventory()->saveLoadWithSerializer(ser), 7 * 32); LOAD_ENTRY("objects", getObjects()->saveLoadWithSerializer(ser), 5 * 128); LOAD_ENTRY("entities", getEntities()->saveLoadWithSerializer(ser), 1262 * 40); - LOAD_ENTRY_ONLY("sound", getSound()->saveLoadWithSerializer(ser)); + LOAD_ENTRY_ONLY("sound", getSoundQueue()->saveLoadWithSerializer(ser)); LOAD_ENTRY_ONLY("savepoints", getSavePoints()->saveLoadWithSerializer(ser)); // Update chapter diff --git a/engines/lastexpress/game/scenes.cpp b/engines/lastexpress/game/scenes.cpp index b346c9daf8..408f48044c 100644 --- a/engines/lastexpress/game/scenes.cpp +++ b/engines/lastexpress/game/scenes.cpp @@ -34,6 +34,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -1057,9 +1059,9 @@ void SceneManager::preProcessScene(SceneIndex *index) { // Sound processing Scene *newScene = getScenes()->get(*index); - if (getSound()->isBuffered(kEntityTables4)) { + if (getSoundQueue()->isBuffered(kEntityTables4)) { if (newScene->type != Scene::kTypeReadText || newScene->param1) - getSound()->processEntry(kEntityTables4); + getSoundQueue()->processEntry(kEntityTables4); } // Cleanup beetle sequences @@ -1089,8 +1091,8 @@ void SceneManager::postProcessScene() { if (getFlags()->mouseRightClick) break; - getSound()->updateQueue(); - getSound()->updateSubtitles(); + getSoundQueue()->updateQueue(); + getSoundQueue()->updateSubtitles(); } } @@ -1157,7 +1159,7 @@ void SceneManager::postProcessScene() { if (getState()->time >= kTimeCityGalanta || getProgress().field_18 == 4) break; - getSound()->processEntry(kSoundType7); + getSoundQueue()->processEntry(kSoundType7); getSound()->playSound(kEntityTrain, "LIB050", kFlagDefault); switch (getProgress().chapter) { diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp index 3fb3f8894d..bc4f71e18d 100644 --- a/engines/lastexpress/game/sound.cpp +++ b/engines/lastexpress/game/sound.cpp @@ -31,6 +31,7 @@ #include "lastexpress/game/state.h" #include "lastexpress/sound/entry.h" +#include "lastexpress/sound/queue.h" #include "lastexpress/helpers.h" #include "lastexpress/graphics.h" @@ -39,9 +40,6 @@ namespace LastExpress { -#define SOUNDCACHE_ENTRY_SIZE 92160 -#define SOUNDCACHE_MAX_SIZE 6 - // Letters & messages static const char *const messages[24] = { "", @@ -115,349 +113,32 @@ static const SoundFlag soundFlags[32] = { kFlag3, kFlag3, kFlag3, kFlag3, kFlag3 }; -SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine), _state(0), _currentType(kSoundType16), _flag(0) { +SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine) { + _loopingSoundDuration = 0; + + _queue = new SoundQueue(engine); + + memset(&_lastWarning, 0, sizeof(_lastWarning)); + // 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); - - _subtitlesFlag = 0; - _currentSubtitle = NULL; - - _loopingSoundDuration = 0; } 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); + SAFE_DELETE(_queue); // 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)->getType() != type1 && (*i)->getType() != type2) - (*i)->reset(); - } -} - -void SoundManager::removeFromQueue(EntityIndex entity) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(entity); - if (entry) - entry->reset(); -} - -void SoundManager::removeFromQueue(Common::String filename) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(filename); - if (entry) - entry->reset(); -} - -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 - entry->close(); - 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->getEntity() != kEntityPlayer; - - return (entry != NULL); -} - -////////////////////////////////////////////////////////////////////////// -// Entry -////////////////////////////////////////////////////////////////////////// -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)->_priority + ((*i)->_status.status & kSoundStatusClear1); - - if (newSize < size) { - cacheEntry = (*i); - size = newSize; - } - } - } - - if (entry->_priority <= size) - return false; - - if (!cacheEntry) - error("[SoundManager::setupCache] Cannot find a valid entry"); - - cacheEntry->setInCache(); - - // 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::processEntry(EntityIndex entity) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(entity); - if (entry) { - entry->update(0); - entry->setEntity(kEntityPlayer); - } -} - -void SoundManager::processEntry(SoundType type) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(type); - if (entry) - entry->update(0); -} - -void SoundManager::setupEntry(SoundType type, EntityIndex index) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(type); - if (entry) - entry->setEntity(index); -} - -void SoundManager::processEntry(Common::String filename) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(filename); - if (entry) { - entry->update(0); - entry->setEntity(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 -////////////////////////////////////////////////////////////////////////// -SoundEntry *SoundManager::getEntry(EntityIndex index) { - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - if ((*i)->getEntity() == index) - return *i; - } - - return NULL; -} - -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; -} - -SoundEntry *SoundManager::getEntry(SoundType type) { - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - if ((*i)->getType() == type) - return *i; - } - - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -// Savegame -////////////////////////////////////////////////////////////////////////// -void SoundManager::saveLoadWithSerializer(Common::Serializer &s) { - Common::StackLock locker(_mutex); - - s.syncAsUint32LE(_state); - s.syncAsUint32LE(_currentType); - - // Compute the number of entries to save - uint32 numEntries = count(); - s.syncAsUint32LE(numEntries); - - // Save or load each entry data - if (s.isSaving()) { - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - (*i)->saveLoadWithSerializer(s); - } else { - warning("Sound::saveLoadWithSerializer: loading 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 +// Sound-related functions ////////////////////////////////////////////////////////////////////////// void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundFlag flag, byte a4) { - if (isBuffered(entity) && entity) - removeFromQueue(entity); + if (_queue->isBuffered(entity) && entity) + _queue->removeFromQueue(entity); SoundFlag currentFlag = (flag == -1) ? getSoundFlag(entity) : (SoundFlag)(flag | 0x80000); @@ -473,8 +154,6 @@ void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundF bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4) { SoundEntry *entry = new SoundEntry(_engine); - Common::StackLock locker(_mutex); - entry->open(filename, flag, 30); entry->_entity = entity; @@ -623,13 +302,13 @@ void SoundManager::playSteam(CityIndex index) { if (index >= ARRAYSIZE(cities)) error("SoundManager::playSteam: invalid city index (was %d, max %d)", index, ARRAYSIZE(cities)); - _state |= kSoundState2; + _queue->resetState(kSoundState2); - if (!getEntry(kSoundType1)) + if (!_queue->getEntry(kSoundType1)) playSoundWithSubtitles("STEAM.SND", kFlagSteam, kEntitySteam); // Get the new sound entry and show subtitles - SoundEntry *entry = getEntry(kSoundType1); + SoundEntry *entry = _queue->getEntry(kSoundType1); if (entry) entry->showSubtitle(cities[index]); } @@ -679,8 +358,8 @@ void SoundManager::playFightSound(byte action, byte a4) { } void SoundManager::playDialog(EntityIndex entity, EntityIndex entityDialog, SoundFlag flag, byte a4) { - if (isBuffered(getDialogName(entityDialog))) - removeFromQueue(getDialogName(entityDialog)); + if (_queue->isBuffered(getDialogName(entityDialog))) + _queue->removeFromQueue(getDialogName(entityDialog)); playSound(entity, getDialogName(entityDialog), flag, a4); } @@ -993,7 +672,7 @@ const char *SoundManager::getDialogName(EntityIndex entity) const { // Letters & Messages ////////////////////////////////////////////////////////////////////////// void SoundManager::readText(int id){ - if (!isBuffered(kEntityTables4)) + if (!_queue->isBuffered(kEntityTables4)) return; if (id < 0 || (id > 8 && id < 50) || id > 64) @@ -1004,8 +683,8 @@ void SoundManager::readText(int id){ // Check if file is in cache for id [1;8] if (id <= 8) - if (isBuffered(text)) - removeFromQueue(text); + if (_queue->isBuffered(text)) + _queue->removeFromQueue(text); playSound(kEntityTables4, text, kFlagDefault); } @@ -1193,7 +872,7 @@ void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compar } void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag flag) { - if (isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain) + if (_queue->isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain) return; if (entity2 == kEntityFrancois || entity2 == kEntityMax) @@ -1598,72 +1277,17 @@ SoundFlag SoundManager::getSoundFlag(EntityIndex entity) const { } ////////////////////////////////////////////////////////////////////////// -// 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)->getSoundEntry(); - SoundStatus status = (SoundStatus)soundEntry->_status.status; - - if (!(status & kSoundStatus_40) - || status & kSoundStatus_180 - || soundEntry->_time == 0 - || (status & kSoundStatusClear1) < 6 - || ((getFlags()->nis & 0x8000) && soundEntry->_priority < 90)) { - current_index = 0; - } else { - current_index = soundEntry->_priority + (status & kSoundStatusClear1); - - if (_currentSubtitle == (*i)) - current_index += 4; - } - - if (index < current_index) { - index = current_index; - subtitle = (*i); - } - } - - if (_currentSubtitle == subtitle) { - if (subtitle) - subtitle->setupAndDraw(); - - return; - } - - if (_subtitlesFlag & 1) - subtitle->drawOnScreen(); - - if (subtitle) { - subtitle->loadData(); - subtitle->setupAndDraw(); - } -} - -////////////////////////////////////////////////////////////////////////// // Misc ////////////////////////////////////////////////////////////////////////// void SoundManager::playLoopingSound(int param) { - Common::List<SoundEntry *>::iterator snd; - char tmp[80]; + SoundEntry *entry = _queue->getEntry(kSoundType1); - for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) { - if ((*snd)->getType() == kSoundType1) - break; - } - - byte numLoops[8]; static const EntityPosition positions[8] = { kPosition_8200, kPosition_7500, kPosition_6470, kPosition_5790, kPosition_4840, kPosition_4070, kPosition_3050, kPosition_2740 }; + byte numLoops[8]; numLoops[1] = 4; numLoops[2] = 2; numLoops[3] = 2; @@ -1671,13 +1295,14 @@ void SoundManager::playLoopingSound(int param) { numLoops[5] = 2; numLoops[6] = 2; + char tmp[80]; tmp[0] = 0; int partNumber = 1; int fnameLen = 6; - if (_state & 1 && param >= 0x45 && param <= 0x46) { - if (_state & 2) { + if (_queue->getSoundState() & 1 && param >= 0x45 && param <= 0x46) { + if (_queue->getSoundState() & 2) { strcpy(tmp, "STEAM.SND"); _loopingSoundDuration = 32767; @@ -1727,390 +1352,28 @@ void SoundManager::playLoopingSound(int param) { } } - if (partNumber != 99) { + if (partNumber != 99) sprintf(tmp, "LOOP%d%c.SND", partNumber, _engine->getRandom().getRandomNumber(numLoops[partNumber] - 1) + 'A'); - } } if (getFlags()->flag_3) fnameLen = 5; - if (!*snd || scumm_strnicmp((*snd)->_name2.c_str(), tmp, fnameLen)) { + if (!entry || scumm_strnicmp(entry->_name2.c_str(), tmp, fnameLen)) { _loopingSoundDuration = _engine->getRandom().getRandomNumber(319) + 260; if (partNumber != 99) { playSoundWithSubtitles(tmp, kFlagLoopedSound, kEntitySteam); - if (*snd) - (*snd)->update(0); + if (entry) + entry->update(0); - for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) { - if ((*snd)->getType() == kSoundType1) { - (*snd)->update(7); - break; - } - } + SoundEntry *entry1 = _queue->getEntry(kSoundType1); + if (entry1) + entry1->update(7); } } } } -void SoundManager::stopAllSound() { - Common::StackLock locker(_mutex); - - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - (*i)->_soundStream->stop(); -} - -////////////////////////////////////////////////////////////////////////// -// Sound filter -////////////////////////////////////////////////////////////////////////// - -static const int filterData[1424] = { - 0, 0, 0, 0, 128, 256, 384, 512, 0, 0, 0, 0, 128, 256, - 384, 512, 0, 0, 0, 0, 192, 320, 448, 576, 0, 0, 0, 0, - 192, 320, 448, 576, 64, 64, 64, 64, 256, 384, 512, 640, - 64, 64, 64, 64, 256, 384, 512, 640, 128, 128, 128, 128, - 320, 448, 576, 704, 128, 128, 128, 128, 320, 448, 576, - 704, 192, 192, 192, 192, 384, 512, 640, 768, 192, 192, - 192, 192, 384, 512, 640, 768, 256, 256, 256, 256, 448, - 576, 704, 832, 256, 256, 256, 256, 448, 576, 704, 832, - 320, 320, 320, 320, 512, 640, 768, 896, 320, 320, 320, - 320, 512, 640, 768, 896, 384, 384, 384, 384, 576, 704, - 832, 960, 384, 384, 384, 384, 576, 704, 832, 960, 448, - 448, 448, 448, 640, 768, 896, 1024, 448, 448, 448, 448, - 640, 768, 896, 1024, 512, 512, 512, 512, 704, 832, 960, - 1088, 512, 512, 512, 512, 704, 832, 960, 1088, 576, - 576, 576, 576, 768, 896, 1024, 1152, 576, 576, 576, - 576, 768, 896, 1024, 1152, 640, 640, 640, 640, 832, - 960, 1088, 1216, 640, 640, 640, 640, 832, 960, 1088, - 1216, 704, 704, 704, 704, 896, 1024, 1152, 1280, 704, - 704, 704, 704, 896, 1024, 1152, 1280, 768, 768, 768, - 768, 960, 1088, 1216, 1344, 768, 768, 768, 768, 960, - 1088, 1216, 1344, 832, 832, 832, 832, 1024, 1152, 1280, - 1408, 832, 832, 832, 832, 1024, 1152, 1280, 1408, 896, - 896, 896, 896, 1088, 1216, 1344, 1472, 896, 896, 896, - 896, 1088, 1216, 1344, 1472, 960, 960, 960, 960, 1152, - 1280, 1408, 1536, 960, 960, 960, 960, 1152, 1280, 1408, - 1536, 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, - 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, 1088, - 1088, 1088, 1088, 1280, 1408, 1536, 1664, 1088, 1088, - 1088, 1088, 1280, 1408, 1536, 1664, 1152, 1152, 1152, - 1152, 1344, 1472, 1600, 1728, 1152, 1152, 1152, 1152, - 1344, 1472, 1600, 1728, 1216, 1216, 1216, 1216, 1408, - 1536, 1664, 1792, 1216, 1216, 1216, 1216, 1408, 1536, - 1664, 1792, 1280, 1280, 1280, 1280, 1472, 1600, 1728, - 1856, 1280, 1280, 1280, 1280, 1472, 1600, 1728, 1856, - 1344, 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1344, - 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1408, 1408, - 1408, 1408, 1600, 1728, 1856, 1984, 1408, 1408, 1408, - 1408, 1600, 1728, 1856, 1984, 1472, 1472, 1472, 1472, - 1664, 1792, 1920, 2048, 1472, 1472, 1472, 1472, 1664, - 1792, 1920, 2048, 1536, 1536, 1536, 1536, 1728, 1856, - 1984, 2112, 1536, 1536, 1536, 1536, 1728, 1856, 1984, - 2112, 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, - 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, 1664, - 1664, 1664, 1664, 1856, 1984, 2112, 2240, 1664, 1664, - 1664, 1664, 1856, 1984, 2112, 2240, 1728, 1728, 1728, - 1728, 1920, 2048, 2176, 2304, 1728, 1728, 1728, 1728, - 1920, 2048, 2176, 2304, 1792, 1792, 1792, 1792, 1984, - 2112, 2240, 2368, 1792, 1792, 1792, 1792, 1984, 2112, - 2240, 2368, 1856, 1856, 1856, 1856, 2048, 2176, 2304, - 2432, 1856, 1856, 1856, 1856, 2048, 2176, 2304, 2432, - 1920, 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1920, - 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1984, 1984, - 1984, 1984, 2176, 2304, 2432, 2560, 1984, 1984, 1984, - 1984, 2176, 2304, 2432, 2560, 2048, 2048, 2048, 2048, - 2240, 2368, 2496, 2624, 2048, 2048, 2048, 2048, 2240, - 2368, 2496, 2624, 2112, 2112, 2112, 2112, 2304, 2432, - 2560, 2688, 2112, 2112, 2112, 2112, 2304, 2432, 2560, - 2688, 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, - 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, 2240, - 2240, 2240, 2240, 2432, 2560, 2688, 2816, 2240, 2240, - 2240, 2240, 2432, 2560, 2688, 2816, 2304, 2304, 2304, - 2304, 2496, 2624, 2752, 2880, 2304, 2304, 2304, 2304, - 2496, 2624, 2752, 2880, 2368, 2368, 2368, 2368, 2560, - 2688, 2816, 2944, 2368, 2368, 2368, 2368, 2560, 2688, - 2816, 2944, 2432, 2432, 2432, 2432, 2624, 2752, 2880, - 3008, 2432, 2432, 2432, 2432, 2624, 2752, 2880, 3008, - 2496, 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2496, - 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2560, 2560, - 2560, 2560, 2752, 2880, 3008, 3136, 2560, 2560, 2560, - 2560, 2752, 2880, 3008, 3136, 2624, 2624, 2624, 2624, - 2816, 2944, 3072, 3200, 2624, 2624, 2624, 2624, 2816, - 2944, 3072, 3200, 2688, 2688, 2688, 2688, 2880, 3008, - 3136, 3264, 2688, 2688, 2688, 2688, 2880, 3008, 3136, - 3264, 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, - 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, 2816, - 2816, 2816, 2816, 3008, 3136, 3264, 3392, 2816, 2816, - 2816, 2816, 3008, 3136, 3264, 3392, 2880, 2880, 2880, - 2880, 3072, 3200, 3328, 3456, 2880, 2880, 2880, 2880, - 3072, 3200, 3328, 3456, 2944, 2944, 2944, 2944, 3136, - 3264, 3392, 3520, 2944, 2944, 2944, 2944, 3136, 3264, - 3392, 3520, 3008, 3008, 3008, 3008, 3200, 3328, 3456, - 3584, 3008, 3008, 3008, 3008, 3200, 3328, 3456, 3584, - 3072, 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3072, - 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3136, 3136, - 3136, 3136, 3328, 3456, 3584, 3712, 3136, 3136, 3136, - 3136, 3328, 3456, 3584, 3712, 3200, 3200, 3200, 3200, - 3392, 3520, 3648, 3776, 3200, 3200, 3200, 3200, 3392, - 3520, 3648, 3776, 3264, 3264, 3264, 3264, 3456, 3584, - 3712, 3840, 3264, 3264, 3264, 3264, 3456, 3584, 3712, - 3840, 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, - 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, 3392, - 3392, 3392, 3392, 3584, 3712, 3840, 3968, 3392, 3392, - 3392, 3392, 3584, 3712, 3840, 3968, 3456, 3456, 3456, - 3456, 3648, 3776, 3904, 4032, 3456, 3456, 3456, 3456, - 3648, 3776, 3904, 4032, 3520, 3520, 3520, 3520, 3712, - 3840, 3968, 4096, 3520, 3520, 3520, 3520, 3712, 3840, - 3968, 4096, 3584, 3584, 3584, 3584, 3776, 3904, 4032, - 4160, 3584, 3584, 3584, 3584, 3776, 3904, 4032, 4160, - 3648, 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3648, - 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3712, 3712, - 3712, 3712, 3904, 4032, 4160, 4288, 3712, 3712, 3712, - 3712, 3904, 4032, 4160, 4288, 3776, 3776, 3776, 3776, - 3968, 4096, 4224, 4352, 3776, 3776, 3776, 3776, 3968, - 4096, 4224, 4352, 3840, 3840, 3840, 3840, 4032, 4160, - 4288, 4416, 3840, 3840, 3840, 3840, 4032, 4160, 4288, - 4416, 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, - 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, 3968, - 3968, 3968, 3968, 4160, 4288, 4416, 4544, 3968, 3968, - 3968, 3968, 4160, 4288, 4416, 4544, 4032, 4032, 4032, - 4032, 4224, 4352, 4480, 4608, 4032, 4032, 4032, 4032, - 4224, 4352, 4480, 4608, 4096, 4096, 4096, 4096, 4288, - 4416, 4544, 4672, 4096, 4096, 4096, 4096, 4288, 4416, - 4544, 4672, 4160, 4160, 4160, 4160, 4352, 4480, 4608, - 4736, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736, - 4224, 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4224, - 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4288, 4288, - 4288, 4288, 4480, 4608, 4736, 4864, 4288, 4288, 4288, - 4288, 4480, 4608, 4736, 4864, 4352, 4352, 4352, 4352, - 4544, 4672, 4800, 4928, 4352, 4352, 4352, 4352, 4544, - 4672, 4800, 4928, 4416, 4416, 4416, 4416, 4608, 4736, - 4864, 4992, 4416, 4416, 4416, 4416, 4608, 4736, 4864, - 4992, 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, - 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, 4544, - 4544, 4544, 4544, 4736, 4864, 4992, 5120, 4544, 4544, - 4544, 4544, 4736, 4864, 4992, 5120, 4608, 4608, 4608, - 4608, 4800, 4928, 5056, 5184, 4608, 4608, 4608, 4608, - 4800, 4928, 5056, 5184, 4672, 4672, 4672, 4672, 4864, - 4992, 5120, 5248, 4672, 4672, 4672, 4672, 4864, 4992, - 5120, 5248, 4736, 4736, 4736, 4736, 4928, 5056, 5184, - 5312, 4736, 4736, 4736, 4736, 4928, 5056, 5184, 5312, - 4800, 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4800, - 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4864, 4864, - 4864, 4864, 5056, 5184, 5312, 5440, 4864, 4864, 4864, - 4864, 5056, 5184, 5312, 5440, 4928, 4928, 4928, 4928, - 5120, 5248, 5376, 5504, 4928, 4928, 4928, 4928, 5120, - 5248, 5376, 5504, 4992, 4992, 4992, 4992, 5184, 5312, - 5440, 5568, 4992, 4992, 4992, 4992, 5184, 5312, 5440, - 5568, 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, - 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, 5120, - 5120, 5120, 5120, 5312, 5440, 5568, 5632, 5120, 5120, - 5120, 5120, 5312, 5440, 5568, 5632, 5184, 5184, 5184, - 5184, 5376, 5504, 5632, 5632, 5184, 5184, 5184, 5184, - 5376, 5504, 5632, 5632, 5248, 5248, 5248, 5248, 5440, - 5568, 5632, 5632, 5248, 5248, 5248, 5248, 5440, 5568, - 5632, 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, - 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, 5632, - 5376, 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5376, - 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5440, 5440, - 5440, 5440, 5632, 5632, 5632, 5632, 5440, 5440, 5440, - 5440, 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, - 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, 5632, - 5632, 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, - 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, 5632, - 5632 -}; - -static const int filterData2[1424] = { - 0, 2, 4, 6, 7, 9, 11, 13, 0, -2, -4, -6, -7, -9, -11, - -13, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, - -11, -13, -15, 1, 3, 5, 7, 10, 12, 14, 16, -1, -3, -5, - -7, -10, -12, -14, -16, 1, 3, 6, 8, 11, 13, 16, 18, - -1, -3, -6, -8, -11, -13, -16, -18, 1, 4, 6, 9, 12, - 15, 17, 20, -1, -4, -6, -9, -12, -15, -17, -20, 1, 4, - 7, 10, 13, 16, 19, 22, -1, -4, -7, -10, -13, -16, -19, - -22, 1, 4, 8, 11, 14, 17, 21, 24, -1, -4, -8, -11, -14, - -17, -21, -24, 1, 5, 8, 12, 15, 19, 22, 26, -1, -5, - -8, -12, -15, -19, -22, -26, 2, 6, 10, 14, 18, 22, 26, - 30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10, - 14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27, - -31, 2, 7, 11, 16, 21, 26, 30, 35, -2, -7, -11, -16, - -21, -26, -30, -35, 2, 7, 13, 18, 23, 28, 34, 39, -2, - -7, -13, -18, -23, -28, -34, -39, 2, 8, 14, 20, 25, - 31, 37, 43, -2, -8, -14, -20, -25, -31, -37, -43, 3, - 9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34, - -40, -46, 3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17, - -24, -31, -38, -45, -52, 3, 11, 19, 27, 34, 42, 50, - 58, -3, -11, -19, -27, -34, -42, -50, -58, 4, 12, 21, - 29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55, - -63, 4, 13, 23, 32, 41, 50, 60, 69, -4, -13, -23, -32, - -41, -50, -60, -69, 5, 15, 25, 35, 46, 56, 66, 76, -5, - -15, -25, -35, -46, -56, -66, -76, 5, 16, 28, 39, 50, - 61, 73, 84, -5, -16, -28, -39, -50, -61, -73, -84, 6, - 18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56, - -68, -81, -93, 6, 20, 34, 48, 61, 75, 89, 103, -6, -20, - -34, -48, -61, -75, -89, -103, 7, 22, 37, 52, 67, 82, - 97, 112, -7, -22, -37, -52, -67, -82, -97, -112, 8, - 24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74, - -90, -107, -123, 9, 27, 45, 63, 82, 100, 118, 136, -9, - -27, -45, -63, -82, -100, -118, -136, 10, 30, 50, 70, - 90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130, - -150, 11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55, - -77, -99, -121, -143, -165, 12, 36, 60, 84, 109, 133, - 157, 181, -12, -36, -60, -84, -109, -133, -157, -181, - 13, 40, 66, 93, 120, 147, 173, 200, -13, -40, -66, -93, - -120, -147, -173, -200, 14, 44, 73, 103, 132, 162, 191, - 221, -14, -44, -73, -103, -132, -162, -191, -221, 16, - 48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113, - -146, -178, -211, -243, 17, 53, 89, 125, 160, 196, 232, - 268, -17, -53, -89, -125, -160, -196, -232, -268, 19, - 58, 98, 137, 176, 215, 255, 294, -19, -58, -98, -137, - -176, -215, -255, -294, 21, 64, 108, 151, 194, 237, - 281, 324, -21, -64, -108, -151, -194, -237, -281, -324, - 23, 71, 118, 166, 213, 261, 308, 356, -23, -71, -118, - -166, -213, -261, -308, -356, 26, 78, 130, 182, 235, - 287, 339, 391, -26, -78, -130, -182, -235, -287, -339, - -391, 28, 86, 143, 201, 258, 316, 373, 431, -28, -86, - -143, -201, -258, -316, -373, -431, 31, 94, 158, 221, - 284, 347, 411, 474, -31, -94, -158, -221, -284, -347, - -411, -474, 34, 104, 174, 244, 313, 383, 453, 523, -34, - -104, -174, -244, -313, -383, -453, -523, 38, 115, 191, - 268, 345, 422, 498, 575, -38, -115, -191, -268, -345, - -422, -498, -575, 42, 126, 210, 294, 379, 463, 547, - 631, -42, -126, -210, -294, -379, -463, -547, -631, - 46, 139, 231, 324, 417, 510, 602, 695, -46, -139, -231, - -324, -417, -510, -602, -695, 51, 153, 255, 357, 459, - 561, 663, 765, -51, -153, -255, -357, -459, -561, -663, - -765, 56, 168, 280, 392, 505, 617, 729, 841, -56, -168, - -280, -392, -505, -617, -729, -841, 61, 185, 308, 432, - 555, 679, 802, 926, -61, -185, -308, -432, -555, -679, - -802, -926, 68, 204, 340, 476, 612, 748, 884, 1020, - -68, -204, -340, -476, -612, -748, -884, -1020, 74, - 224, 373, 523, 672, 822, 971, 1121, -74, -224, -373, - -523, -672, -822, -971, -1121, 82, 246, 411, 575, 740, - 904, 1069, 1233, -82, -246, -411, -575, -740, -904, - -1069, -1233, 90, 271, 452, 633, 814, 995, 1176, 1357, - -90, -271, -452, -633, -814, -995, -1176, -1357, 99, - 298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497, - -696, -895, -1094, -1293, -1492, 109, 328, 547, 766, - 985, 1204, 1423, 1642, -109, -328, -547, -766, -985, - -1204, -1423, -1642, 120, 361, 601, 842, 1083, 1324, - 1564, 1805, -120, -361, -601, -842, -1083, -1324, -1564, - -1805, 132, 397, 662, 927, 1192, 1457, 1722, 1987, -132, - -397, -662, -927, -1192, -1457, -1722, -1987, 145, 437, - 728, 1020, 1311, 1603, 1894, 2186, -145, -437, -728, - -1020, -1311, -1603, -1894, -2186, 160, 480, 801, 1121, - 1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442, - -1762, -2083, -2403, 176, 529, 881, 1234, 1587, 1940, - 2292, 2645, -176, -529, -881, -1234, -1587, -1940, -2292, - -2645, 194, 582, 970, 1358, 1746, 2134, 2522, 2910, - -194, -582, -970, -1358, -1746, -2134, -2522, -2910, - 213, 640, 1066, 1493, 1920, 2347, 2773, 3200, -213, - -640, -1066, -1493, -1920, -2347, -2773, -3200, 234, - 704, 1173, 1643, 2112, 2582, 3051, 3521, -234, -704, - -1173, -1643, -2112, -2582, -3051, -3521, 258, 774, - 1291, 1807, 2324, 2840, 3357, 3873, -258, -774, -1291, - -1807, -2324, -2840, -3357, -3873, 284, 852, 1420, 1988, - 2556, 3124, 3692, 4260, -284, -852, -1420, -1988, -2556, - -3124, -3692, -4260, 312, 937, 1561, 2186, 2811, 3436, - 4060, 4685, -312, -937, -1561, -2186, -2811, -3436, - -4060, -4685, 343, 1030, 1718, 2405, 3092, 3779, 4467, - 5154, -343, -1030, -1718, -2405, -3092, -3779, -4467, - -5154, 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670, - -378, -1134, -1890, -2646, -3402, -4158, -4914, -5670, - 415, 1247, 2079, 2911, 3742, 4574, 5406, 6238, -415, - -1247, -2079, -2911, -3742, -4574, -5406, -6238, 457, - 1372, 2287, 3202, 4117, 5032, 5947, 6862, -457, -1372, - -2287, -3202, -4117, -5032, -5947, -6862, 503, 1509, - 2516, 3522, 4529, 5535, 6542, 7548, -503, -1509, -2516, - -3522, -4529, -5535, -6542, -7548, 553, 1660, 2767, - 3874, 4981, 6088, 7195, 8302, -553, -1660, -2767, -3874, - -4981, -6088, -7195, -8302, 608, 1826, 3044, 4262, 5479, - 6697, 7915, 9133, -608, -1826, -3044, -4262, -5479, - -6697, -7915, -9133, 669, 2009, 3348, 4688, 6027, 7367, - 8706, 10046, -669, -2009, -3348, -4688, -6027, -7367, - -8706, -10046, 736, 2210, 3683, 5157, 6630, 8104, 9577, - 11051, -736, -2210, -3683, -5157, -6630, -8104, -9577, - -11051, 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157, - -810, -2431, -4052, -5673, -7294, -8915, -10536, -12157, - 891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, -891, - -2674, -4457, -6240, -8023, -9806, -11589, -13372, 980, - 2941, 4903, 6864, 8825, 10786, 12748, 14709, -980, -2941, - -4903, -6864, -8825, -10786, -12748, -14709, 1078, 3236, - 5393, 7551, 9708, 11866, 14023, 16181, -1078, -3236, - -5393, -7551, -9708, -11866, -14023, -16181, 1186, 3559, - 5933, 8306, 10679, 13052, 15426, 17799, -1186, -3559, - -5933, -8306, -10679, -13052, -15426, -17799, 1305, - 3915, 6526, 9136, 11747, 14357, 16968, 19578, -1305, - -3915, -6526, -9136, -11747, -14357, -16968, -19578, - 1435, 4307, 7179, 10051, 12922, 15794, 18666, 21538, - -1435, -4307, -7179, -10051, -12922, -15794, -18666, - -21538, 1579, 4738, 7896, 11055, 14214, 17373, 20531, - 23690, -1579, -4738, -7896, -11055, -14214, -17373, - -20531, -23690, 1737, 5212, 8686, 12161, 15636, 19111, - 22585, 26060, -1737, -5212, -8686, -12161, -15636, -19111, - -22585, -26060, 1911, 5733, 9555, 13377, 17200, 21022, - 24844, 28666, -1911, -5733, -9555, -13377, -17200, -21022, - -24844, -28666, 2102, 6306, 10511, 14715, 18920, 23124, - 27329, 31533, -2102, -6306, -10511, -14715, -18920, - -23124, -27329, -31533, 2312, 6937, 11562, 16187, 20812, - 25437, 30062, 32767, -2312, -6937, -11562, -16187, -20812, - -25437, -30062, -32767, 2543, 7631, 12718, 17806, 22893, - 27981, 32767, 32767, -2543, -7631, -12718, -17806, -22893, - -27981, -32767, -32767, 2798, 8394, 13990, 19586, 25183, - 30779, 32767, 32767, -2798, -8394, -13990, -19586, -25183, - -30779, -32767, -32767, 3077, 9233, 15389, 21545, 27700, - 32767, 32767, 32767, -3077, -9233, -15389, -21545, -27700, - -32767, -32767, -32767, 3385, 10157, 16928, 23700, 30471, - 32767, 32767, 32767, -3385, -10157, -16928, -23700, - -30471, -32767, -32767, -32767, 3724, 11172, 18621, - 26069, 32767, 32767, 32767, 32767, -3724, -11172, -18621, - -26069, -32767, -32767, -32767, -32767, 4095, 12287, - 20479, 28671, 32767, 32767, 32767, 32767, -4095, -12287, - -20479, -28671, -32767, -32767, -32767, -32767 -}; - -static const int p1s[17] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 0 }; -static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 1 }; - -static void soundFilter(byte *data, int16 *buffer, int p1, int p2); - -void SoundManager::applyFilter(SoundEntry *entry, int16 *buffer) { - if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) { - entry->_status.status |= 0x20000000; - } else { - int variant = entry->_status.status & 0x1f; - - soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]); - } -} - - -static void soundFilter(byte *data, int16 *buffer, int p1, int p2) { - int data1, data2, data1p, data2p; - byte idx; - - data2 = data[0]; - data1 = data[1] << 6; - - data += 2; - - for (int count = 0; count < 735; count++) { - idx = data[count] >> 4; - data1p = filterData[idx + data1]; - data2p = CLIP(filterData2[idx + data1] + data2, -32767, 32767); - - buffer[2 * count] = (p2 * data2p) >> p1; - - idx = data[count] & 0xF; - - data1 = filterData[idx + data1p]; - data2 = CLIP(filterData2[idx + data1p] + data2p, -32767, 32767); - buffer[2 * count + 1] = (p2 * data2) >> p1; - } -} - - } // End of namespace LastExpress diff --git a/engines/lastexpress/game/sound.h b/engines/lastexpress/game/sound.h index 414fb0d028..797e52646e 100644 --- a/engines/lastexpress/game/sound.h +++ b/engines/lastexpress/game/sound.h @@ -25,55 +25,18 @@ #include "lastexpress/shared.h" -#include "lastexpress/helpers.h" - -#include "common/list.h" -#include "common/mutex.h" -#include "common/system.h" -#include "common/serializer.h" +#include "common/str.h" namespace LastExpress { class LastExpressEngine; -class SubtitleManager; -class SoundEntry; -class SubtitleEntry; +class SoundQueue; -class SoundManager : Common::Serializable { +class SoundManager { public: SoundManager(LastExpressEngine *engine); ~SoundManager(); - // Timer - void handleTimer(); - - // State - void resetState() { _state |= kSoundType1; } - - // Sound queue - void updateQueue(); - void resetQueue(SoundType type1, SoundType type2 = kSoundTypeNone); - void clearQueue(); - - // Subtitles - void updateSubtitles(); - - // Entry - bool isBuffered(Common::String filename, bool testForEntity = false); - bool isBuffered(EntityIndex entity); - void setupEntry(SoundType type, EntityIndex index); - void processEntry(EntityIndex entity); - void processEntry(SoundType type); - void processEntry(Common::String filename); - void processEntries(); - void removeFromQueue(Common::String filename); - void removeFromQueue(EntityIndex entity); - uint32 getEntryTime(EntityIndex index); - - // Misc - void unknownFunction4(); - void clearStatus(); - // Sound playing void playSound(EntityIndex entity, Common::String filename, SoundFlag flag = kFlagInvalid, byte a4 = 0); bool playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4 = 0); @@ -83,7 +46,6 @@ public: void playFightSound(byte action, byte a4); void playLocomotiveSound(); void playWarningCompartment(EntityIndex entity, ObjectIndex compartment); - void playLoopingSound(int param); // Dialog & Letters @@ -97,64 +59,16 @@ public: const char *wrongDoorCath() const; const char *justAMinuteCath() const; - // FLags + // Flags SoundFlag getSoundFlag(EntityIndex index) const; - // Debug - void stopAllSound(); - - // Serializable - void saveLoadWithSerializer(Common::Serializer &ser); - uint32 count(); - // Accessors - uint32 getFlag() { return _flag; } - int getSubtitleFlag() { return _subtitlesFlag; } - void setSubtitleFlag(int flag) { _subtitlesFlag = flag; } - SoundType getCurrentType() { return _currentType; } - void setCurrentType(SoundType type) { _currentType = type; } + SoundQueue *getQueue() { return _queue; } uint32 getData2() { return _data2; } - // Subtitles - void addSubtitle(SubtitleEntry *entry) { _subtitles.push_back(entry); } - void removeSubtitle(SubtitleEntry *entry) { _subtitles.remove(entry); } - void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; } - SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; } - - // Queue - bool setupCache(SoundEntry *entry); - void addToQueue(SoundEntry *entry) { _soundList.push_back(entry); } - - SoundEntry *getEntry(SoundType type); - private: - typedef int32 *SoundBuffer; - - enum SoundState { - kSoundState0 = 0, - kSoundState1 = 1, - kSoundState2 = 2 - }; - - // Engine LastExpressEngine *_engine; - - // State flag - int _state; - SoundType _currentType; - - Common::Mutex _mutex; - - // Unknown data - uint32 _data0; - uint32 _data1; - uint32 _data2; - - // TODO: this seems to be a synchronization flag for the sound timer - uint32 _flag; - - // Filters - int32 _buffer[2940]; ///< Static sound buffer + SoundQueue *_queue; // Compartment warnings by Mertens or Coudert uint32 _lastWarning[12]; @@ -162,23 +76,10 @@ private: // Looping sound int _loopingSoundDuration; - // Sound entries - Common::List<SoundEntry *> _soundList; ///< List of all sound entries - Common::List<SoundEntry *> _soundCache; ///< List of entries with a data buffer - void *_soundCacheData; - - SoundEntry *getEntry(EntityIndex index); - SoundEntry *getEntry(Common::String name); - - void removeFromCache(SoundEntry *entry); - - // Subtitles - int _subtitlesFlag; - Common::List<SubtitleEntry *> _subtitles; - SubtitleEntry *_currentSubtitle; - - // Sound filter - void applyFilter(SoundEntry *entry, int16 *buffer); + // Unknown data + uint32 _data0; + uint32 _data1; + uint32 _data2; }; } // End of namespace LastExpress |