diff options
Diffstat (limited to 'engines/lastexpress')
-rw-r--r-- | engines/lastexpress/data/snd.cpp | 81 | ||||
-rw-r--r-- | engines/lastexpress/game/savegame.cpp | 12 | ||||
-rw-r--r-- | engines/lastexpress/lastexpress.cpp | 3 | ||||
-rw-r--r-- | engines/lastexpress/lastexpress.h | 1 | ||||
-rw-r--r-- | engines/lastexpress/module.mk | 2 | ||||
-rw-r--r-- | engines/lastexpress/shared.h | 17 | ||||
-rw-r--r-- | engines/lastexpress/sound/entry.cpp | 6 | ||||
-rw-r--r-- | engines/lastexpress/sound/queue.cpp | 88 | ||||
-rw-r--r-- | engines/lastexpress/sound/sound.cpp | 4 |
9 files changed, 80 insertions, 134 deletions
diff --git a/engines/lastexpress/data/snd.cpp b/engines/lastexpress/data/snd.cpp index 28d20df9bd..6845be8808 100644 --- a/engines/lastexpress/data/snd.cpp +++ b/engines/lastexpress/data/snd.cpp @@ -38,7 +38,7 @@ namespace LastExpress { #pragma region Sound filters tables -static const int filterData[1424] = { +static const int stepTable[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, @@ -152,7 +152,7 @@ static const int filterData[1424] = { 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, - 4.6, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736, + 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, @@ -195,7 +195,7 @@ static const int filterData[1424] = { 5632 }; -static const int filterData2[1424] = { +static const int imaTable[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, @@ -352,16 +352,20 @@ static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, // Last Express ADPCM is similar to MS IMA mono, but inverts its nibbles // and does not have the 4 byte per channel requirement -class LastExpress_ADPCMStream : public Audio::Ima_ADPCMStream { +class LastExpress_ADPCMStream : public Audio::ADPCMStream { public: LastExpress_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, uint32 blockSize, int32 filterId) : - Audio::Ima_ADPCMStream(stream, disposeAfterUse, size, 44100, 1, blockSize) { + Audio::ADPCMStream(stream, disposeAfterUse, size, 44100, 1, blockSize) { _currentFilterId = -1; _nextFilterId = filterId; } int readBuffer(int16 *buffer, const int numSamples) { int samples = 0; + // Temporary data + int step = 0; + int sample = 0; + byte idx = 0; assert(numSamples % 2 == 0); @@ -369,15 +373,37 @@ public: if (_blockPos[0] == _blockAlign) { // read block header _status.ima_ch[0].last = _stream->readSint16LE(); - _status.ima_ch[0].stepIndex = _stream->readSint16LE(); + _status.ima_ch[0].stepIndex = _stream->readSint16LE() << 6; _blockPos[0] = 4; + + // Get current filter + _currentFilterId = _nextFilterId; + _nextFilterId = -1; + + // No filter: skip decoding + if (_currentFilterId == -1) + break; + + // Compute step adjustment + _stepAdjust1 = p1s[_currentFilterId]; + _stepAdjust2 = p2s[_currentFilterId]; } for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 2) { byte data = _stream->readByte(); _blockPos[0]++; - buffer[samples] = decodeIMA((data >> 4) & 0x0f); - buffer[samples + 1] = decodeIMA(data & 0x0f); + + // First nibble + idx = data >> 4; + step = stepTable[idx + _status.ima_ch[0].stepIndex / 4]; + sample = CLIP(imaTable[idx + _status.ima_ch[0].stepIndex / 4] + _status.ima_ch[0].last, -32767, 32767); + buffer[samples] = (_stepAdjust2 * sample) >> _stepAdjust1; + + // Second nibble + idx = data & 0xF; + _status.ima_ch[0].stepIndex = stepTable[idx + step / 4]; + _status.ima_ch[0].last = CLIP(imaTable[idx + step / 4] + sample, -32767, 32767); + buffer[samples + 1] = (_stepAdjust2 * _status.ima_ch[0].last) >> _stepAdjust1; } } @@ -387,41 +413,10 @@ public: void setFilterId(int32 filterId) { _nextFilterId = filterId; } private: - int32 _currentFilterId; - int32 _nextFilterId; // the sound filter id, -1 for none - - /** - * Sound filter - * - * @param [in] data If non-null, the input data - * @param [in,out] buffer If non-null, the output buffer. - * @param p1 The first filter input. - * @param p2 The second filter input. - */ - 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; - } - } + int32 _currentFilterId; + int32 _nextFilterId; // the sound filter id, -1 for none + int32 _stepAdjust1; + int32 _stepAdjust2; }; ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp index ebada5dd4e..57c18b5697 100644 --- a/engines/lastexpress/game/savegame.cpp +++ b/engines/lastexpress/game/savegame.cpp @@ -45,12 +45,12 @@ namespace LastExpress { static const struct { const char *saveFile; } gameInfo[6] = { - {"blue.egg"}, - {"red.egg"}, - {"green.egg"}, - {"purple.egg"}, - {"teal.egg"}, - {"gold.egg"} + {"lastexpress-blue.egg"}, + {"lastexpress-red.egg"}, + {"lastexpress-green.egg"}, + {"lastexpress-purple.egg"}, + {"lastexpress-teal.egg"}, + {"lastexpress-gold.egg"} }; ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/lastexpress.cpp b/engines/lastexpress/lastexpress.cpp index 885ca8b212..250fa0f2d0 100644 --- a/engines/lastexpress/lastexpress.cpp +++ b/engines/lastexpress/lastexpress.cpp @@ -42,6 +42,7 @@ #include "common/debug-channels.h" #include "common/error.h" #include "common/fs.h" +#include "common/timer.h" #include "engines/util.h" @@ -146,7 +147,7 @@ Common::Error LastExpressEngine::run() { // Start sound manager and setup timer _soundMan = new SoundManager(this); - _timer->installTimerProc(&soundTimer, 17000, this); + _timer->installTimerProc(&soundTimer, 17000, this, "lastexpressSound"); // Menu _menu = new Menu(this); diff --git a/engines/lastexpress/lastexpress.h b/engines/lastexpress/lastexpress.h index f8f38788a0..1431b79b9f 100644 --- a/engines/lastexpress/lastexpress.h +++ b/engines/lastexpress/lastexpress.h @@ -27,7 +27,6 @@ #include "lastexpress/eventhandler.h" #include "common/random.h" -#include "common/timer.h" #include "engines/engine.h" diff --git a/engines/lastexpress/module.mk b/engines/lastexpress/module.mk index a11a7c4b67..8b3287d5d7 100644 --- a/engines/lastexpress/module.mk +++ b/engines/lastexpress/module.mk @@ -80,4 +80,4 @@ PLUGIN := 1 endif # Include common rules -include $(srcdir)/rules.mk
\ No newline at end of file +include $(srcdir)/rules.mk diff --git a/engines/lastexpress/shared.h b/engines/lastexpress/shared.h index 7b640c773a..d60a498447 100644 --- a/engines/lastexpress/shared.h +++ b/engines/lastexpress/shared.h @@ -84,29 +84,26 @@ enum SoundFlag { }; enum SoundState { - kSoundState0 = 0, - kSoundState1 = 1, - kSoundState2 = 2 + kSoundStateNone = 0, + kSoundState1 = 1, + kSoundState2 = 2 }; enum SoundStatus { + kSoundStatusClear0 = 0x10, + kSoundStatusFilter = 0x1F, kSoundStatus_20 = 0x20, kSoundStatus_40 = 0x40, + kSoundStatusCached = 0x80, kSoundStatus_180 = 0x180, kSoundStatusClosed = 0x200, kSoundStatus_400 = 0x400, - + kSoundStatusClear4 = 0x800, kSoundStatus_8000 = 0x8000, kSoundStatus_20000 = 0x20000, kSoundStatus_100000 = 0x100000, kSoundStatus_20000000 = 0x20000000, kSoundStatus_40000000 = 0x40000000, - - kSoundStatusClear0 = 0x10, - kSoundStatusFilter = 0x1F, - kSoundStatusCached = 0x80, - kSoundStatusClear3 = 0x200, - kSoundStatusClear4 = 0x800, kSoundStatusClearAll = 0xFFFFFFE0 }; diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp index 87d8ccdb30..44cc68a57b 100644 --- a/engines/lastexpress/sound/entry.cpp +++ b/engines/lastexpress/sound/entry.cpp @@ -88,8 +88,8 @@ void SoundEntry::close() { _status.status |= kSoundStatusClosed; // Loop until ready - while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1)) - ; // empty loop body + //while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->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 @@ -290,7 +290,7 @@ bool SoundEntry::updateSound() { } } } - //if (status.status2 & 0x40 && !((uint32)_status.status & 0x180) && v1->soundBuffer) + //if (status.status2 & 0x40 && !((uint32)_status.status & 0x180) && v1->soundBuffer) // Sound_FillSoundBuffer(v1); } result = true; diff --git a/engines/lastexpress/sound/queue.cpp b/engines/lastexpress/sound/queue.cpp index 0a6442ceed..33b4c06793 100644 --- a/engines/lastexpress/sound/queue.cpp +++ b/engines/lastexpress/sound/queue.cpp @@ -102,80 +102,41 @@ void SoundQueue::removeFromQueue(Common::String filename) { } void SoundQueue::updateQueue() { - //Common::StackLock locker(_mutex); - - //warning("[Sound::updateQueue] Not implemented"); - - int maxPriority = 0; - Common::List<SoundEntry *>::iterator lsnd; - SoundEntry *msnd; - - bool loopedPlaying; - - loopedPlaying = 0; - //++g_sound_flag; + Common::StackLock locker(_mutex); - for (lsnd = _soundList.begin(); lsnd != _soundList.end(); ++lsnd) { - if ((*lsnd)->getType() == kSoundType1) - break; - } + ++_flag; - if (getSoundState() & 1) { - if (!(*lsnd) || getFlags()->flag_3 || (*lsnd && (*lsnd)->getTime() > getSound()->getLoopingSoundDuration())) { + if (getSoundState() & kSoundState1) { + SoundEntry *entry = getEntry(kSoundType1); + if (!entry || getFlags()->flag_3 || (entry && entry->getTime() > getSound()->getLoopingSoundDuration())) { getSound()->playLoopingSound(0x45); } else { if (getSound()->getData1() && getSound()->getData2() >= getSound()->getData1()) { - (*lsnd)->update(getSound()->getData0()); + entry->update(getSound()->getData0()); getSound()->setData1(0); } } } - msnd = NULL; - - for (lsnd = _soundList.begin(); lsnd != _soundList.end(); ++lsnd) { - if ((*lsnd)->getStatus().status2 & 0x1) { // Sound is stopped - // original code - //if ((*lsnd)->soundBuffer) - // Sound_RemoveSoundDataFromCache(*lsnd); - //if ((*lsnd)->archive) { - // Archive_SetStatusNotLoaded((*lsnd)->archive); - // (*lsnd)->archive = 0; - // (*lsnd)->field_28 = 3; - //} - - if (_soundList.size() < 6) { - if ((*lsnd)->getStatus().status1 & 0x1F) { - int pri = (*lsnd)->getPriority() + ((*lsnd)->getStatus().status1 & 0x1F); - - if (pri > maxPriority) { - msnd = *lsnd; - maxPriority = pri; - } - } - } - } + for (Common::List<SoundEntry *>::iterator it = _soundList.begin(); it != _soundList.end(); ++it) { + SoundEntry *entry = *it; - if (!(*lsnd)->updateSound() && !((*lsnd)->getStatus().status3 & 0x8)) { - if (msnd == *lsnd) { - maxPriority = 0; - msnd = 0; - } - if (*lsnd) { - (*lsnd)->close(); - SAFE_DELETE(*lsnd); - lsnd = _soundList.reverse_erase(lsnd); - } + // Original removes the entry data from the cache and sets the archive as not loaded + // and if the sound data buffer is not full, loads a new entry to be played based on + // its priority and filter id + + if (!entry->updateSound() && !(entry->getStatus().status3 & 0x8)) { + entry->close(); + SAFE_DELETE(entry); + it = _soundList.reverse_erase(it); } } - - // We don't need this - //if (msnd) - // msnd->updateEntryInternal(); + // Original update the current entry, loading another set of samples to be decoded getFlags()->flag_3 = 0; - //--g_sound_flag; + + --_flag; } void SoundQueue::resetQueue() { @@ -209,17 +170,10 @@ void SoundQueue::resetQueue(SoundType type1, SoundType type2) { } void SoundQueue::clearQueue() { - _flag |= 4; - - // FIXME: Wait a while for a flag to be set - //for (int i = 0; i < 3000000; i++) - // if (_flag & 8) - // break; + Common::StackLock locker(_mutex); _flag |= 8; - Common::StackLock locker(_mutex); - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { SoundEntry *entry = (*i); @@ -240,7 +194,7 @@ void SoundQueue::clearStatus() { Common::StackLock locker(_mutex); for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - (*i)->setStatus((*i)->getStatus().status | kSoundStatusClear3); + (*i)->setStatus((*i)->getStatus().status | kSoundStatusClosed); } ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/sound/sound.cpp b/engines/lastexpress/sound/sound.cpp index c04b6d361f..2f7bb4a601 100644 --- a/engines/lastexpress/sound/sound.cpp +++ b/engines/lastexpress/sound/sound.cpp @@ -1305,8 +1305,8 @@ void SoundManager::playLoopingSound(int param) { int partNumber = 1; int fnameLen = 6; - if (_queue->getSoundState() & 1 && param >= 0x45 && param <= 0x46) { - if (_queue->getSoundState() & 2) { + if (_queue->getSoundState() & kSoundState1 && param >= 0x45 && param <= 0x46) { + if (_queue->getSoundState() & kSoundState2) { strcpy(tmp, "STEAM.SND"); _loopingSoundDuration = 32767; |