From aa64280b55609d11ab869d0b7cea9775a8e0d291 Mon Sep 17 00:00:00 2001 From: Littleboy Date: Wed, 11 May 2011 19:12:19 -0400 Subject: LASTEXPRESS: Implement SoundManager::setupCache() --- engines/lastexpress/game/sound.cpp | 65 ++++++++++++++++++++++++++++++++++++-- engines/lastexpress/game/sound.h | 13 ++++++-- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp index 7125b95985..5cfe99035e 100644 --- a/engines/lastexpress/game/sound.cpp +++ b/engines/lastexpress/game/sound.cpp @@ -36,6 +36,9 @@ namespace LastExpress { +#define SOUNDCACHE_ENTRY_SIZE 92160 +#define SOUNDCACHE_MAX_SIZE 6 + // Letters & messages const char *messages[24] = { "", @@ -109,6 +112,9 @@ SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine), _state( memset(&_buffer, 0, sizeof(_buffer)); memset(&_lastWarning, 0, sizeof(_lastWarning)); + // Sound cache + _soundCacheData = malloc(6 * SOUNDCACHE_ENTRY_SIZE); + _drawSubtitles = 0; _currentSubtitle = NULL; } @@ -124,6 +130,8 @@ SoundManager::~SoundManager() { _currentSubtitle = NULL; + free(_soundCacheData); + // Zero passed pointers _engine = NULL; } @@ -154,7 +162,7 @@ void SoundManager::handleTimer() { ////////////////////////////////////////////////////////////////////////// void SoundManager::updateQueue() { // TODO add mutex lock! - //warning("Sound::unknownFunction1: not implemented!"); + warning("Sound::updateQueue: not implemented!"); } void SoundManager::resetQueue(SoundType type1, SoundType type2) { @@ -328,11 +336,64 @@ void SoundManager::setEntryStatus(SoundEntry *entry, FlagType flag) const { entry->status.status = (status | kSoundStatusClear4); } +void SoundManager::setInCache(SoundEntry *entry) { + entry->status.status |= kSoundStatusClear2; +} + bool SoundManager::setupCache(SoundEntry *entry) { - warning("Sound::setupCache: not implemented!"); + if (entry->soundData) + return true; + + if (_cache.size() >= SOUNDCACHE_MAX_SIZE) { + + SoundEntry *cacheEntry = NULL; + uint32 size = 1000; + + for (Common::List::iterator i = _cache.begin(); i != _cache.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); + + _cache.push_back(entry); + entry->soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_cache.size() - 1); + } else { + _cache.push_back(entry); + entry->soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_cache.size() - 1); + } + return true; } +void SoundManager::removeFromCache(SoundEntry *entry) { + for (Common::List::iterator i = _cache.begin(); i != _cache.end(); ++i) { + if ((*i) == entry) { + // Remove sound buffer + entry->soundData = NULL; + + // Remove entry from sound cache + i = _cache.reverse_erase(i); + } + } +} + void SoundManager::clearStatus() { Common::StackLock locker(_mutex); diff --git a/engines/lastexpress/game/sound.h b/engines/lastexpress/game/sound.h index 37aff5c072..08ec767022 100644 --- a/engines/lastexpress/game/sound.h +++ b/engines/lastexpress/game/sound.h @@ -206,6 +206,7 @@ private: enum SoundStatus { kSoundStatus_20 = 0x20, kSoundStatus_40 = 0x40, + kSoundStatus_180 = 0x180, kSoundStatusRemoved = 0x200, kSoundStatus_400 = 0x400, @@ -247,8 +248,8 @@ private: SoundType type; // int //int field_8; //int field_C; - //int field_10; - //int fileData; + int processedFrameCount; + void *soundData; //int field_18; int field_1C; uint32 time; @@ -262,7 +263,7 @@ private: int field_40; EntityIndex entity; int field_48; - int field_4C; + uint32 field_4C; Common::String name1; //char[16]; Common::String name2; //char[16]; //int next; // offset to the next structure in the list (not used) @@ -275,6 +276,9 @@ private: status.status = 0; type = kSoundTypeNone; + processedFrameCount = 0; + soundData = NULL; + field_1C = 0; time = 0; @@ -345,6 +349,7 @@ private: // Sound cache Common::List _cache; + void *_soundCacheData; SoundEntry *getEntry(EntityIndex index); SoundEntry *getEntry(Common::String name); @@ -353,7 +358,9 @@ private: void setupEntry(SoundEntry *entry, Common::String name, FlagType flag, int a4); void setEntryType(SoundEntry *entry, FlagType flag); void setEntryStatus(SoundEntry *entry, FlagType flag) const; + void setInCache(SoundEntry *entry); bool setupCache(SoundEntry *entry); + void removeFromCache(SoundEntry *entry); void loadSoundData(SoundEntry *entry, Common::String name); void updateEntry(SoundEntry *entry, uint value) const; -- cgit v1.2.3