mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-24 05:01:43 +00:00
LASTEXPRESS: Replace shared sound buffer by per-entry buffer
This commit is contained in:
parent
b0ee7bbb7e
commit
9cc5d404c7
@ -38,6 +38,8 @@
|
||||
|
||||
namespace LastExpress {
|
||||
|
||||
#define SOUNDCACHE_ENTRY_SIZE 92160
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SoundEntry
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -45,7 +47,7 @@ SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
|
||||
_type = kSoundTypeNone;
|
||||
|
||||
_currentDataPtr = 0;
|
||||
_soundData = NULL;
|
||||
_soundBuffer = NULL;
|
||||
|
||||
_blockCount = 0;
|
||||
_time = 0;
|
||||
@ -66,12 +68,13 @@ SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
|
||||
}
|
||||
|
||||
SoundEntry::~SoundEntry() {
|
||||
// Entries that have been queued would have their streamed disposed automatically
|
||||
// Entries that have been queued will have their streamed disposed automatically
|
||||
if (!_soundStream)
|
||||
SAFE_DELETE(_stream);
|
||||
|
||||
delete _soundStream;
|
||||
|
||||
free(_soundBuffer);
|
||||
|
||||
// Zero passed pointers
|
||||
_engine = NULL;
|
||||
}
|
||||
@ -85,7 +88,7 @@ void SoundEntry::open(Common::String name, SoundFlag flag, int priority) {
|
||||
getSoundQueue()->addToQueue(this);
|
||||
|
||||
// Add entry to cache and load sound data
|
||||
getSoundQueue()->setupCache(this);
|
||||
setupCache();
|
||||
loadSoundData(name);
|
||||
}
|
||||
|
||||
@ -197,6 +200,16 @@ void SoundEntry::setStatus(SoundFlag flag) {
|
||||
_status.status = (statusFlag | kSoundStatusClear4);
|
||||
}
|
||||
|
||||
void SoundEntry::setupCache() {
|
||||
if (_soundBuffer)
|
||||
return;
|
||||
|
||||
// Original has a priority-based shared buffer (of 6 entries)
|
||||
// We simply allocate a new buffer for each sound entry that needs it
|
||||
_soundBuffer = (byte *)malloc(SOUNDCACHE_ENTRY_SIZE);
|
||||
memset(_soundBuffer, 0, SOUNDCACHE_ENTRY_SIZE);
|
||||
}
|
||||
|
||||
void SoundEntry::setInCache() {
|
||||
_status.status |= kSoundStatusClear2;
|
||||
}
|
||||
|
@ -152,10 +152,7 @@ public:
|
||||
// Streams
|
||||
Common::SeekableReadStream *getStream() { return _stream; }
|
||||
StreamedSound *getStreamedSound() { return _soundStream; }
|
||||
|
||||
public:
|
||||
// TODO replace by on-the-fly allocated buffer
|
||||
void *_soundData;
|
||||
byte *getSoundBuffer() { return _soundBuffer; }
|
||||
|
||||
private:
|
||||
LastExpressEngine *_engine;
|
||||
@ -184,8 +181,11 @@ private:
|
||||
// original has pointer to the next structure in the list (not used)
|
||||
SubtitleEntry *_subtitle;
|
||||
|
||||
// Sound stream
|
||||
// Sound buffer & stream
|
||||
byte *_soundBuffer;
|
||||
StreamedSound *_soundStream;
|
||||
|
||||
void setupCache();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -32,18 +32,11 @@
|
||||
|
||||
namespace LastExpress {
|
||||
|
||||
#define SOUNDCACHE_ENTRY_SIZE 92160
|
||||
#define SOUNDCACHE_MAX_SIZE 6
|
||||
|
||||
SoundQueue::SoundQueue(LastExpressEngine *engine) : _engine(engine) {
|
||||
_state = 0;
|
||||
_currentType = kSoundType16;
|
||||
_flag = 0;
|
||||
|
||||
// Cache and filter buffers
|
||||
memset(&_buffer, 0, sizeof(_buffer));
|
||||
_soundCacheData = malloc(6 * SOUNDCACHE_ENTRY_SIZE);
|
||||
|
||||
_subtitlesFlag = 0;
|
||||
_currentSubtitle = NULL;
|
||||
}
|
||||
@ -53,17 +46,12 @@ SoundQueue::~SoundQueue() {
|
||||
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;
|
||||
}
|
||||
@ -333,66 +321,6 @@ void SoundQueue::updateSubtitles() {
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Cache
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool SoundQueue::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)->getStatus().status & kSoundStatus_180)) {
|
||||
uint32 newSize = (*i)->getPriority() + ((*i)->getStatus().status & kSoundStatusClear1);
|
||||
|
||||
if (newSize < size) {
|
||||
cacheEntry = (*i);
|
||||
size = newSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entry->getPriority() <= 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->getStatus().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 SoundQueue::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Savegame
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -746,12 +674,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 SoundQueue::applyFilter(SoundEntry *entry, int16 *buffer) {
|
||||
if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) {
|
||||
if ((((byte *)entry->getSoundBuffer())[1] << 6) > 0x1600) {
|
||||
entry->setStatus(entry->getStatus().status | kSoundStatus_20000000);
|
||||
} else {
|
||||
int variant = entry->getStatus().status & 0x1f;
|
||||
|
||||
soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]);
|
||||
soundFilter((byte *)entry->getSoundBuffer(), buffer, p1s[variant], p2s[variant]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,9 +78,6 @@ public:
|
||||
void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; }
|
||||
SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; }
|
||||
|
||||
// Cache
|
||||
bool setupCache(SoundEntry *entry);
|
||||
|
||||
// Serializable
|
||||
void saveLoadWithSerializer(Common::Serializer &ser);
|
||||
uint32 count();
|
||||
@ -109,7 +106,6 @@ private:
|
||||
|
||||
// Entries
|
||||
Common::List<SoundEntry *> _soundList; ///< List of all sound entries
|
||||
Common::List<SoundEntry *> _soundCache; ///< List of entries with a data buffer
|
||||
void *_soundCacheData;
|
||||
|
||||
// Subtitles
|
||||
@ -117,10 +113,6 @@ private:
|
||||
Common::List<SubtitleEntry *> _subtitles;
|
||||
SubtitleEntry *_currentSubtitle;
|
||||
|
||||
// Filters
|
||||
int32 _buffer[2940]; ///< Static sound buffer
|
||||
|
||||
void removeFromCache(SoundEntry *entry);
|
||||
void applyFilter(SoundEntry *entry, int16 *buffer);
|
||||
|
||||
friend class Debugger;
|
||||
|
Loading…
x
Reference in New Issue
Block a user