diff options
-rw-r--r-- | engines/lastexpress/game/sound.cpp | 258 | ||||
-rw-r--r-- | engines/lastexpress/game/sound.h | 18 | ||||
-rw-r--r-- | engines/lastexpress/sound/entry.cpp | 254 | ||||
-rw-r--r-- | engines/lastexpress/sound/entry.h | 97 |
4 files changed, 325 insertions, 302 deletions
diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp index c95ef85701..3fb3f8894d 100644 --- a/engines/lastexpress/game/sound.cpp +++ b/engines/lastexpress/game/sound.cpp @@ -161,15 +161,15 @@ void SoundManager::handleTimer() { for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { SoundEntry *entry = (*i); - if (entry->stream == NULL) { + if (entry->_stream == NULL) { SAFE_DELETE(*i); i = _soundList.reverse_erase(i); continue; - } else if (!entry->soundStream) { - entry->soundStream = new StreamedSound(); + } else if (!entry->_soundStream) { + entry->_soundStream = new StreamedSound(); // TODO: stream any sound in the queue after filtering - entry->soundStream->load(entry->stream); + entry->_soundStream->load(entry->_stream); } } } @@ -189,7 +189,7 @@ void SoundManager::resetQueue(SoundType type1, SoundType type2) { Common::StackLock locker(_mutex); for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - if ((*i)->type != type1 && (*i)->type != type2) + if ((*i)->getType() != type1 && (*i)->getType() != type2) (*i)->reset(); } } @@ -226,7 +226,7 @@ void SoundManager::clearQueue() { SoundEntry *entry = (*i); // Delete entry - removeEntry(entry); + entry->close(); SAFE_DELETE(entry); i = _soundList.reverse_erase(i); @@ -247,7 +247,7 @@ bool SoundManager::isBuffered(Common::String filename, bool testForEntity) { SoundEntry *entry = getEntry(filename); if (testForEntity) - return entry != NULL && !entry->entity; + return entry != NULL && entry->getEntity() != kEntityPlayer; return (entry != NULL); } @@ -255,96 +255,8 @@ bool SoundManager::isBuffered(Common::String filename, bool testForEntity) { ////////////////////////////////////////////////////////////////////////// // Entry ////////////////////////////////////////////////////////////////////////// -void SoundManager::setupEntry(SoundEntry *entry, Common::String name, SoundFlag flag, int priority) { - if (!entry) - error("SoundManager::setupEntry: Invalid entry!"); - - entry->priority = priority; - setEntryType(entry, flag); - entry->setStatus(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, SoundFlag flag) { - switch (flag & kFlagType9) { - default: - case kFlagNone: - entry->type = _currentType; - _currentType = (SoundType)(_currentType + 1); - break; - - case kFlagType1_2: { - SoundEntry *previous2 = getEntry(kSoundType2); - if (previous2) - previous2->update(0); - - SoundEntry *previous = getEntry(kSoundType1); - if (previous) { - previous->type = kSoundType2; - previous->update(0); - } - - entry->type = kSoundType1; - } - break; - - case kFlagType3: { - SoundEntry *previous = getEntry(kSoundType3); - if (previous) { - previous->type = kSoundType4; - previous->update(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; - } -} - bool SoundManager::setupCache(SoundEntry *entry) { - if (entry->soundData) + if (entry->_soundData) return true; if (_soundCache.size() >= SOUNDCACHE_MAX_SIZE) { @@ -353,8 +265,8 @@ bool SoundManager::setupCache(SoundEntry *entry) { 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 (!((*i)->_status.status & kSoundStatus_180)) { + uint32 newSize = (*i)->_priority + ((*i)->_status.status & kSoundStatusClear1); if (newSize < size) { cacheEntry = (*i); @@ -363,7 +275,7 @@ bool SoundManager::setupCache(SoundEntry *entry) { } } - if (entry->priority <= size) + if (entry->_priority <= size) return false; if (!cacheEntry) @@ -372,17 +284,17 @@ bool SoundManager::setupCache(SoundEntry *entry) { cacheEntry->setInCache(); // TODO: Wait until the cache entry is ready to be removed - while (!(cacheEntry->status.status1 & 1)) + while (!(cacheEntry->_status.status1 & 1)) ; - if (cacheEntry->soundData) + if (cacheEntry->_soundData) removeFromCache(cacheEntry); _soundCache.push_back(entry); - entry->soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1); + 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); + entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1); } return true; @@ -392,7 +304,7 @@ 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; + entry->_soundData = NULL; // Remove entry from sound cache i = _soundCache.reverse_erase(i); @@ -404,48 +316,7 @@ 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::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) { - entry->subtitle->draw(); - SAFE_DELETE(entry->subtitle); - } - - if (entry->entity) { - if (entry->entity == kEntitySteam) - playLoopingSound(2); - else if (entry->entity != kEntityTrain) - getSavePoints()->push(kEntityPlayer, entry->entity, kActionEndSound); - } + (*i)->_status.status |= kSoundStatusClear3; } void SoundManager::processEntry(EntityIndex entity) { @@ -454,7 +325,7 @@ void SoundManager::processEntry(EntityIndex entity) { SoundEntry *entry = getEntry(entity); if (entry) { entry->update(0); - entry->entity = kEntityPlayer; + entry->setEntity(kEntityPlayer); } } @@ -471,7 +342,7 @@ void SoundManager::setupEntry(SoundType type, EntityIndex index) { SoundEntry *entry = getEntry(type); if (entry) - entry->entity = index; + entry->setEntity(index); } void SoundManager::processEntry(Common::String filename) { @@ -480,7 +351,7 @@ void SoundManager::processEntry(Common::String filename) { SoundEntry *entry = getEntry(filename); if (entry) { entry->update(0); - entry->entity = kEntityPlayer; + entry->setEntity(kEntityPlayer); } } @@ -496,7 +367,7 @@ uint32 SoundManager::getEntryTime(EntityIndex index) { SoundEntry *entry = getEntry(index); if (entry) - return entry->time; + return entry->_time; return 0; } @@ -515,7 +386,7 @@ void SoundManager::unknownFunction4() { ////////////////////////////////////////////////////////////////////////// SoundEntry *SoundManager::getEntry(EntityIndex index) { for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - if ((*i)->entity == index) + if ((*i)->getEntity() == index) return *i; } @@ -527,7 +398,7 @@ SoundEntry *SoundManager::getEntry(Common::String name) { name += ".SND"; for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - if ((*i)->name2 == name) + if ((*i)->_name2 == name) return *i; } @@ -536,7 +407,7 @@ SoundEntry *SoundManager::getEntry(Common::String name) { SoundEntry *SoundManager::getEntry(SoundType type) { for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - if ((*i)->type == type) + if ((*i)->getType() == type) return *i; } @@ -547,6 +418,8 @@ SoundEntry *SoundManager::getEntry(SoundType type) { // Savegame ////////////////////////////////////////////////////////////////////////// void SoundManager::saveLoadWithSerializer(Common::Serializer &s) { + Common::StackLock locker(_mutex); + s.syncAsUint32LE(_state); s.syncAsUint32LE(_currentType); @@ -554,39 +427,12 @@ void SoundManager::saveLoadWithSerializer(Common::Serializer &s) { 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->blockCount); // 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 blockCount = (uint32)entry->field_48 - _data2; - if (blockCount > kFlag8) - blockCount = 0; - s.syncAsUint32LE(blockCount); // blockCount; - - s.syncAsUint32LE(entry->priority); // 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); - } - } + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) + (*i)->saveLoadWithSerializer(s); } else { - warning("Sound::saveLoadWithSerializer: not implemented!"); + warning("Sound::saveLoadWithSerializer: loading not implemented"); s.skip(numEntries * 64); } } @@ -600,7 +446,7 @@ uint32 SoundManager::count() { uint32 numEntries = 0; for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - if ((*i)->name2.matchString("NISSND?")) + if ((*i)->_name2.matchString("NISSND?")) ++numEntries; return numEntries; @@ -629,12 +475,12 @@ bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag fla Common::StackLock locker(_mutex); - setupEntry(entry, filename, flag, 30); - entry->entity = entity; + entry->open(filename, flag, 30); + entry->_entity = entity; if (a4) { - entry->field_48 = _data2 + 2 * a4; - entry->status.status |= kSoundStatus_8000; + entry->_field_48 = _data2 + 2 * a4; + entry->_status.status |= kSoundStatus_8000; } else { // Get subtitles name while (filename.size() > 4) @@ -644,7 +490,7 @@ bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag fla entry->updateState(); } - return (entry->type != kSoundTypeNone); + return (entry->getType() != kSoundTypeNone); } void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) { @@ -1763,16 +1609,16 @@ void SoundManager::updateSubtitles() { 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; + SoundStatus status = (SoundStatus)soundEntry->_status.status; if (!(status & kSoundStatus_40) - || status & 0x180 - || soundEntry->time == 0 - || (status & 0x1F) < 6 - || ((getFlags()->nis & 0x8000) && soundEntry->priority < 90)) { + || status & kSoundStatus_180 + || soundEntry->_time == 0 + || (status & kSoundStatusClear1) < 6 + || ((getFlags()->nis & 0x8000) && soundEntry->_priority < 90)) { current_index = 0; } else { - current_index = soundEntry->priority + (status & 0x1F); + current_index = soundEntry->_priority + (status & kSoundStatusClear1); if (_currentSubtitle == (*i)) current_index += 4; @@ -1808,15 +1654,15 @@ void SoundManager::playLoopingSound(int param) { char tmp[80]; for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) { - if ((*snd)->type == kSoundType1) + 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 }; + kPosition_6470, kPosition_5790, + kPosition_4840, kPosition_4070, + kPosition_3050, kPosition_2740 }; numLoops[1] = 4; numLoops[2] = 2; @@ -1889,7 +1735,7 @@ void SoundManager::playLoopingSound(int param) { if (getFlags()->flag_3) fnameLen = 5; - if (!*snd || scumm_strnicmp((*snd)->name2.c_str(), tmp, fnameLen)) { + if (!*snd || scumm_strnicmp((*snd)->_name2.c_str(), tmp, fnameLen)) { _loopingSoundDuration = _engine->getRandom().getRandomNumber(319) + 260; if (partNumber != 99) { @@ -1899,7 +1745,7 @@ void SoundManager::playLoopingSound(int param) { (*snd)->update(0); for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) { - if ((*snd)->type == kSoundType1) { + if ((*snd)->getType() == kSoundType1) { (*snd)->update(7); break; } @@ -1913,7 +1759,7 @@ void SoundManager::stopAllSound() { Common::StackLock locker(_mutex); for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - (*i)->soundStream->stop(); + (*i)->_soundStream->stop(); } ////////////////////////////////////////////////////////////////////////// @@ -2232,12 +2078,12 @@ static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 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; + if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) { + entry->_status.status |= 0x20000000; } else { - int variant = entry->status.status & 0x1f; + int variant = entry->_status.status & 0x1f; - soundFilter((byte *)entry->soundData, buffer, p1s[variant], p2s[variant]); + soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]); } } diff --git a/engines/lastexpress/game/sound.h b/engines/lastexpress/game/sound.h index e7b06609a9..414fb0d028 100644 --- a/engines/lastexpress/game/sound.h +++ b/engines/lastexpress/game/sound.h @@ -84,6 +84,8 @@ public: void playLocomotiveSound(); void playWarningCompartment(EntityIndex entity, ObjectIndex compartment); + void playLoopingSound(int param); + // Dialog & Letters void readText(int id); const char *getDialogName(EntityIndex entity) const; @@ -109,6 +111,9 @@ public: uint32 getFlag() { return _flag; } int getSubtitleFlag() { return _subtitlesFlag; } void setSubtitleFlag(int flag) { _subtitlesFlag = flag; } + SoundType getCurrentType() { return _currentType; } + void setCurrentType(SoundType type) { _currentType = type; } + uint32 getData2() { return _data2; } // Subtitles void addSubtitle(SubtitleEntry *entry) { _subtitles.push_back(entry); } @@ -116,6 +121,12 @@ public: 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; @@ -149,7 +160,6 @@ private: uint32 _lastWarning[12]; // Looping sound - void playLoopingSound(int param); int _loopingSoundDuration; // Sound entries @@ -159,14 +169,8 @@ private: SoundEntry *getEntry(EntityIndex index); SoundEntry *getEntry(Common::String name); - SoundEntry *getEntry(SoundType type); - void setupEntry(SoundEntry *entry, Common::String name, SoundFlag flag, int priority); - void setEntryType(SoundEntry *entry, SoundFlag flag); - bool setupCache(SoundEntry *entry); void removeFromCache(SoundEntry *entry); - void loadSoundData(SoundEntry *entry, Common::String name); - void removeEntry(SoundEntry *entry); // Subtitles int _subtitlesFlag; diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp index 67549cb5fe..304d524f45 100644 --- a/engines/lastexpress/sound/entry.cpp +++ b/engines/lastexpress/sound/entry.cpp @@ -22,7 +22,10 @@ #include "lastexpress/sound/entry.h" +#include "lastexpress/game/logic.h" +#include "lastexpress/game/savepoint.h" #include "lastexpress/game/sound.h" +#include "lastexpress/game/state.h" #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" @@ -37,114 +40,267 @@ namespace LastExpress { // SoundEntry ////////////////////////////////////////////////////////////////////////// SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) { - type = kSoundTypeNone; + _type = kSoundTypeNone; - currentDataPtr = 0; - soundData = NULL; + _currentDataPtr = 0; + _soundData = NULL; - blockCount = 0; - time = 0; + _blockCount = 0; + _time = 0; - stream = NULL; + _stream = NULL; - field_34 = 0; - field_38 = 0; - field_3C = 0; - field_40 = 0; - entity = kEntityPlayer; - field_48 = 0; - priority = 0; + _field_34 = 0; + _field_38 = 0; + _field_3C = 0; + _field_40 = 0; + _entity = kEntityPlayer; + _field_48 = 0; + _priority = 0; - subtitle = NULL; + _subtitle = NULL; - soundStream = NULL; + _soundStream = NULL; } SoundEntry::~SoundEntry() { // Entries that have been queued would have their streamed disposed automatically - if (!soundStream) - SAFE_DELETE(stream); + if (!_soundStream) + SAFE_DELETE(_stream); - delete soundStream; + delete _soundStream; _engine = NULL; } +void SoundEntry::open(Common::String name, SoundFlag flag, int priority) { + _priority = priority; + setType(flag); + setStatus(flag); + + // Add entry to sound list + getSound()->addToQueue(this); + + // Add entry to cache and load sound data + getSound()->setupCache(this); + loadSoundData(name); +} + +void SoundEntry::close() { + _status.status |= kSoundStatusRemoved; + + // Loop until ready + while (!(_status.status1 & 4) && !(getSound()->getFlag() & 8) && (getSound()->getFlag() & 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 (_subtitle) { + _subtitle->draw(); + SAFE_DELETE(_subtitle); + } + + if (_entity) { + if (_entity == kEntitySteam) + getSound()->playLoopingSound(2); + else if (_entity != kEntityTrain) + getSavePoints()->push(kEntityPlayer, _entity, kActionEndSound); + } +} + +void SoundEntry::setType(SoundFlag flag) { + switch (flag & kFlagType9) { + default: + case kFlagNone: + _type = getSound()->getCurrentType(); + getSound()->setCurrentType((SoundType)(_type + 1)); + break; + + case kFlagType1_2: { + SoundEntry *previous2 = getSound()->getEntry(kSoundType2); + if (previous2) + previous2->update(0); + + SoundEntry *previous = getSound()->getEntry(kSoundType1); + if (previous) { + previous->setType(kSoundType2); + previous->update(0); + } + + _type = kSoundType1; + } + break; + + case kFlagType3: { + SoundEntry *previous = getSound()->getEntry(kSoundType3); + if (previous) { + previous->setType(kSoundType4); + previous->update(0); + } + + _type = kSoundType11; + } + break; + + case kFlagType7: { + SoundEntry *previous = getSound()->getEntry(kSoundType7); + if (previous) + previous->setType(kSoundType8); + + _type = kSoundType7; + } + break; + + case kFlagType9: { + SoundEntry *previous = getSound()->getEntry(kSoundType9); + if (previous) + previous->setType(kSoundType10); + + _type = kSoundType9; + } + break; + + case kFlagType11: { + SoundEntry *previous = getSound()->getEntry(kSoundType11); + if (previous) + previous->setType(kSoundType14); + + _type = kSoundType11; + } + break; + + case kFlagType13: { + SoundEntry *previous = getSound()->getEntry(kSoundType13); + if (previous) + previous->setType(kSoundType14); + + _type = kSoundType13; + } + break; + } +} + void SoundEntry::setStatus(SoundFlag flag) { SoundStatus statusFlag = (SoundStatus)flag; if (!((statusFlag & 0xFF) & kSoundStatusClear1)) statusFlag = (SoundStatus)(statusFlag | kSoundStatusClear2); if (((statusFlag & 0xFF00) >> 8) & kSoundStatusClear0) - status.status = (uint32)statusFlag; + _status.status = (uint32)statusFlag; else - status.status = (statusFlag | kSoundStatusClear4); + _status.status = (statusFlag | kSoundStatusClear4); } void SoundEntry::setInCache() { - status.status |= kSoundStatusClear2; + _status.status |= kSoundStatusClear2; +} + +void SoundEntry::loadSoundData(Common::String name) { + _name2 = name; + + // Load sound data + _stream = getArchive(name); + + if (!_stream) + _stream = getArchive("DEFAULT.SND"); + + if (_stream) { + warning("Sound::loadSoundData: not implemented!"); + } else { + _status.status = kSoundStatusRemoved; + } } void SoundEntry::update(uint val) { - if (!(status.status3 & 64)) { + if (!(_status.status3 & 64)) { int value2 = val; - status.status |= kSoundStatus_100000; + _status.status |= kSoundStatus_100000; if (val) { if (getSound()->getFlag() & 32) { - field_40 = val; + _field_40 = val; value2 = val * 2 + 1; } - field_3C = value2; + _field_3C = value2; } else { - field_3C = 0; - status.status |= kSoundStatus_40000000; + _field_3C = 0; + _status.status |= kSoundStatus_40000000; } } } void SoundEntry::updateState() { if (getSound()->getFlag() & 32) { - if (type != kSoundType9 && type != kSoundType7 && type != kSoundType5) { - uint32 newStatus = status.status & kSoundStatusClear1; + if (_type != kSoundType9 && _type != kSoundType7 && _type != kSoundType5) { + uint32 newStatus = _status.status & kSoundStatusClear1; - status.status &= kSoundStatusClearAll; + _status.status &= kSoundStatusClearAll; - field_40 = newStatus; - status.status |= newStatus * 2 + 1; + _field_40 = newStatus; + _status.status |= newStatus * 2 + 1; } } - status.status |= kSoundStatus_20; + _status.status |= kSoundStatus_20; } void SoundEntry::reset() { - status.status |= kSoundStatusRemoved; - entity = kEntityPlayer; + _status.status |= kSoundStatusRemoved; + _entity = kEntityPlayer; - if (stream) { - if (!soundStream) { - SAFE_DELETE(stream); + if (_stream) { + if (!_soundStream) { + SAFE_DELETE(_stream); } else { - soundStream->stop(); - SAFE_DELETE(soundStream); + _soundStream->stop(); + SAFE_DELETE(_soundStream); } - stream = NULL; + _stream = NULL; } } void SoundEntry::showSubtitle(Common::String filename) { - subtitle = new SubtitleEntry(_engine); - subtitle->load(filename, this); + _subtitle = new SubtitleEntry(_engine); + _subtitle->load(filename, this); - if (subtitle->getStatus().status2 & 4) { - subtitle->draw(); - SAFE_DELETE(subtitle); + if (_subtitle->getStatus().status2 & 4) { + _subtitle->draw(); + SAFE_DELETE(_subtitle); } else { - status.status |= kSoundStatus_20000; + _status.status |= kSoundStatus_20000; + } +} + +void SoundEntry::saveLoadWithSerializer(Common::Serializer &s) { + if (_name2.matchString("NISSND?") && (_status.status & kFlagType7) != kFlag3) { + s.syncAsUint32LE(_status.status); + s.syncAsUint32LE(_type); + s.syncAsUint32LE(_blockCount); // field_8; + s.syncAsUint32LE(_time); + s.syncAsUint32LE(_field_34); // field_10; + s.syncAsUint32LE(_field_38); // field_14; + s.syncAsUint32LE(_entity); + + uint32 delta = (uint32)_field_48 - getSound()->getData2(); + if (delta > kFlag8) + delta = 0; + s.syncAsUint32LE(delta); + + s.syncAsUint32LE(_priority); + + char name1[16]; + strcpy((char *)&name1, _name1.c_str()); + s.syncBytes((byte *)&name1, 16); + + char name2[16]; + strcpy((char *)&name2, _name2.c_str()); + s.syncBytes((byte *)&name2, 16); } } @@ -193,10 +349,10 @@ void SubtitleEntry::setupAndDraw() { _data->load(getArchive(_filename)); } - if (_data->getMaxTime() > _sound->time) { + if (_data->getMaxTime() > _sound->_time) { _status.status = kSoundStatus_400; } else { - _data->setTime((uint16)_sound->time); + _data->setTime((uint16)_sound->_time); if (getSound()->getSubtitleFlag() & 1) drawOnScreen(); diff --git a/engines/lastexpress/sound/entry.h b/engines/lastexpress/sound/entry.h index 84a2342cf3..929d3463d5 100644 --- a/engines/lastexpress/sound/entry.h +++ b/engines/lastexpress/sound/entry.h @@ -24,30 +24,30 @@ #define LASTEXPRESS_SOUND_ENTRY_H /* - Sound entry: 68 bytes (this is what appears in the savegames) - uint32 {4} - ?? - uint32 {4} - ?? - uint32 {4} - ?? - uint32 {4} - ?? + Sound entry: 68 bytes (this is what appears in savegames) + uint32 {4} - status + uint32 {4} - type + uint32 {4} - blockCount + uint32 {4} - time uint32 {4} - ?? uint32 {4} - ?? uint32 {4} - entity uint32 {4} - ?? - uint32 {4} - ?? + uint32 {4} - priority char {16} - name 1 char {16} - name 2 Sound queue entry: 120 bytes uint16 {2} - status + byte {1} - type byte {1} - ?? - byte {1} - ?? - uint32 {4} - ?? - uint32 {4} - ?? - uint32 {4} - ?? - uint32 {4} - file data pointer - uint32 {4} - ?? - uint32 {4} - ?? uint32 {4} - ?? + uint32 {4} - currentDataPtr + uint32 {4} - soundData + uint32 {4} - currentBufferPtr + uint32 {4} - blockCount + uint32 {4} - time + uint32 {4} - size uint32 {4} - ?? uint32 {4} - archive structure pointer uint32 {4} - ?? @@ -57,7 +57,7 @@ uint32 {4} - ?? uint32 {4} - entity uint32 {4} - ?? - uint32 {4} - ?? + uint32 {4} - priority char {16} - name 1 char {16} - name 2 uint32 {4} - pointer to next entry in the queue @@ -69,6 +69,8 @@ #include "lastexpress/shared.h" +#include "common/serializer.h" + namespace LastExpress { class LastExpressEngine; @@ -109,13 +111,18 @@ union SoundStatusUnion { ////////////////////////////////////////////////////////////////////////// // SoundEntry ////////////////////////////////////////////////////////////////////////// -class SoundEntry { +class SoundEntry : Common::Serializable { public: SoundEntry(LastExpressEngine *engine); ~SoundEntry(); + void open(Common::String name, SoundFlag flag, int priority); + void close(); + void setStatus(SoundFlag flag); + void setType(SoundFlag flag); void setInCache(); + void loadSoundData(Common::String name); void update(uint val); void updateState(); void reset(); @@ -123,37 +130,47 @@ public: // Subtitles void showSubtitle(Common::String filename); + // Serializable + void saveLoadWithSerializer(Common::Serializer &ser); + + // Accessors + void setType(SoundType type) { _type = type; } + SoundType getType() { return _type; } + + void setEntity(EntityIndex entity) { _entity = entity; } + EntityIndex getEntity() { return _entity; } + private: LastExpressEngine *_engine; public: - SoundStatusUnion status; - SoundType type; // int - //int data; - //int endOffset; - int currentDataPtr; - void *soundData; - //int currentBufferPtr; - int blockCount; - uint32 time; - //int size; - //int field_28; - Common::SeekableReadStream *stream; // int - //int field_30; - int field_34; - int field_38; - int field_3C; - int field_40; - EntityIndex entity; - int field_48; - uint32 priority; - Common::String name1; //char[16]; - Common::String name2; //char[16]; - //int next; // offset to the next structure in the list (not used) - SubtitleEntry *subtitle; + SoundStatusUnion _status; + SoundType _type; // int + //int _data; + //int _endOffset; + int _currentDataPtr; + void *_soundData; + //int _currentBufferPtr; + int _blockCount; + uint32 _time; + //int _size; + //int _field_28; + Common::SeekableReadStream *_stream; // int + //int _field_30; + int _field_34; + int _field_38; + int _field_3C; + int _field_40; + EntityIndex _entity; + int _field_48; + uint32 _priority; + Common::String _name1; //char[16]; + Common::String _name2; //char[16]; + // original has pointer to the next structure in the list (not used) + SubtitleEntry *_subtitle; // Sound stream - StreamedSound *soundStream; + StreamedSound *_soundStream; }; ////////////////////////////////////////////////////////////////////////// |