mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-17 23:44:22 +00:00
Reworked the sound energy code
svn-id: r35845
This commit is contained in:
parent
6801112956
commit
78776638d3
@ -45,6 +45,8 @@
|
||||
|
||||
#include "engines/engine.h"
|
||||
|
||||
#include "made/sound.h"
|
||||
|
||||
namespace Made {
|
||||
|
||||
enum MadeGameID {
|
||||
@ -115,6 +117,8 @@ public:
|
||||
|
||||
int _soundRate;
|
||||
bool _autoStopSound;
|
||||
uint _soundEnergyIndex;
|
||||
SoundEnergyArray *_soundEnergyArray;
|
||||
|
||||
// 2 = LGOP2, Manhole N&E
|
||||
// 3 = Return to Zork
|
||||
|
@ -157,8 +157,8 @@ SoundResource::SoundResource() : _soundSize(0), _soundData(NULL) {
|
||||
}
|
||||
|
||||
SoundResource::~SoundResource() {
|
||||
if (_soundData)
|
||||
delete[] _soundData;
|
||||
delete[] _soundData;
|
||||
delete _soundEnergyArray;
|
||||
}
|
||||
|
||||
void SoundResource::load(byte *source, int size) {
|
||||
@ -169,7 +169,10 @@ void SoundResource::load(byte *source, int size) {
|
||||
_soundSize = chunkCount * chunkSize;
|
||||
_soundData = new byte[_soundSize];
|
||||
|
||||
decompressSound(source + 14, _soundData, chunkSize, chunkCount);
|
||||
_soundEnergyArray = new SoundEnergyArray;
|
||||
|
||||
decompressSound(source + 14, _soundData, chunkSize, chunkCount, _soundEnergyArray);
|
||||
|
||||
}
|
||||
|
||||
Audio::AudioStream *SoundResource::getAudioStream(int soundRate, bool loop) {
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "graphics/surface.h"
|
||||
#include "sound/audiostream.h"
|
||||
|
||||
#include "made/sound.h"
|
||||
|
||||
namespace Made {
|
||||
|
||||
const int kMaxResourceCacheCount = 100;
|
||||
@ -104,9 +106,11 @@ public:
|
||||
~SoundResource();
|
||||
void load(byte *source, int size);
|
||||
Audio::AudioStream *getAudioStream(int soundRate, bool loop = false);
|
||||
SoundEnergyArray *getSoundEnergyArray() const { return _soundEnergyArray; }
|
||||
protected:
|
||||
byte *_soundData;
|
||||
int _soundSize;
|
||||
SoundEnergyArray *_soundEnergyArray;
|
||||
};
|
||||
|
||||
class MenuResource : public Resource {
|
||||
|
@ -237,8 +237,11 @@ int16 ScriptFunctions::sfPlaySound(int16 argc, int16 *argv) {
|
||||
_vm->_autoStopSound = (argv[0] == 1);
|
||||
}
|
||||
if (soundNum > 0) {
|
||||
SoundResource *soundRes = _vm->_res->getSound(soundNum);
|
||||
_vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle,
|
||||
_vm->_res->getSound(soundNum)->getAudioStream(_vm->_soundRate, false));
|
||||
soundRes->getAudioStream(_vm->_soundRate, false));
|
||||
_vm->_soundEnergyArray = soundRes->getSoundEnergyArray();
|
||||
_vm->_soundEnergyIndex = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -616,20 +619,20 @@ int16 ScriptFunctions::sfGetSoundEnergy(int16 argc, int16 *argv) {
|
||||
// This is called while in-game voices are played to animate
|
||||
// mouths when NPCs are talking
|
||||
|
||||
// FIXME: the mouth animations are out of sync. This occurs
|
||||
// because the original unpacked sounds on the fly, whereas
|
||||
// in ScummVM we unpack them when they're loaded. In ScummVM,
|
||||
// the "sound energy" values are stored in an array (used as
|
||||
// a stack), which means that sfGetSoundEnergy can empty that
|
||||
// array prematurely. A proper fix would be to figure out
|
||||
// when a value should be popped from the sound energy stack,
|
||||
// or to unpack sounds on the fly like the original does
|
||||
|
||||
int result = 0;
|
||||
if (soundEnergy.size() > 0) {
|
||||
result = *soundEnergy.begin();
|
||||
soundEnergy.pop_front();
|
||||
|
||||
if (_vm->_mixer->isSoundHandleActive(_audioStreamHandle) && _vm->_soundEnergyArray &&
|
||||
_vm->_soundEnergyIndex < _vm->_soundEnergyArray->size()) {
|
||||
|
||||
uint32 position = (_vm->_soundRate / 1000) * _vm->_mixer->getSoundElapsedTime(_audioStreamHandle);
|
||||
SoundEnergyItem *soundEnergyItem = &_vm->_soundEnergyArray->operator[](_vm->_soundEnergyIndex);
|
||||
|
||||
result = soundEnergyItem->energy;
|
||||
|
||||
if (position >= soundEnergyItem->position)
|
||||
_vm->_soundEnergyIndex++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -31,9 +31,7 @@
|
||||
|
||||
namespace Made {
|
||||
|
||||
Common::List<int> soundEnergy;
|
||||
|
||||
void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount) {
|
||||
void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray) {
|
||||
|
||||
int16 prevSample = 0, workSample = 0;
|
||||
byte soundBuffer[1025];
|
||||
@ -45,6 +43,8 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
|
||||
uint16 ofs = 0;
|
||||
uint16 i = 0, l = 0;
|
||||
byte val;
|
||||
|
||||
SoundEnergyItem soundEnergyItem;
|
||||
|
||||
const int modeValues[3][4] = {
|
||||
{ 2, 8, 0x01, 1},
|
||||
@ -52,7 +52,10 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
|
||||
{16, 2, 0x0F, 4}
|
||||
};
|
||||
|
||||
soundEnergy.clear();
|
||||
soundEnergyItem.position = 0;
|
||||
|
||||
if (soundEnergyArray)
|
||||
soundEnergyArray->clear();
|
||||
|
||||
while (chunkCount--) {
|
||||
deltaType = (*source) >> 6;
|
||||
@ -71,8 +74,12 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
|
||||
|
||||
case 0:
|
||||
memset(soundBuffer, 0x80, workChunkSize);
|
||||
workSample = 0;
|
||||
soundEnergy.push_back(0);
|
||||
workSample = 0;
|
||||
|
||||
soundEnergyItem.energy = 0;
|
||||
if (soundEnergyArray)
|
||||
soundEnergyArray->push_back(soundEnergyItem);
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@ -99,14 +106,21 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
|
||||
}
|
||||
}
|
||||
|
||||
soundEnergy.push_back(type - 1);
|
||||
soundEnergyItem.energy = type - 1;
|
||||
if (soundEnergyArray)
|
||||
soundEnergyArray->push_back(soundEnergyItem);
|
||||
|
||||
break;
|
||||
|
||||
case 5:
|
||||
for (i = 0; i < workChunkSize; i++)
|
||||
soundBuffer[i] = *source++;
|
||||
workSample = soundBuffer[workChunkSize - 1] - 128;
|
||||
soundEnergy.push_back(type - 1);
|
||||
|
||||
soundEnergyItem.energy = type - 1;
|
||||
if (soundEnergyArray)
|
||||
soundEnergyArray->push_back(soundEnergyItem);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -137,6 +151,7 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
|
||||
prevSample = workSample;
|
||||
memcpy(dest, soundBuffer, chunkSize);
|
||||
dest += chunkSize;
|
||||
soundEnergyItem.position += chunkSize;
|
||||
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,14 @@
|
||||
|
||||
namespace Made {
|
||||
|
||||
extern Common::List<int> soundEnergy;
|
||||
struct SoundEnergyItem {
|
||||
uint32 position;
|
||||
byte energy;
|
||||
};
|
||||
|
||||
void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount);
|
||||
typedef Common::Array<SoundEnergyItem> SoundEnergyArray;
|
||||
|
||||
void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray = NULL);
|
||||
|
||||
} // End of namespace Made
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user