Performed some optimizations to the PMV player

svn-id: r31644
This commit is contained in:
Filippos Karapetis 2008-04-21 16:52:09 +00:00
parent fb76c3eeed
commit 4e62a13a67
2 changed files with 63 additions and 52 deletions

View File

@ -41,18 +41,25 @@ void PmvPlayer::play(const char *filename) {
_mixer->stopAll();
_audioStream = Audio::makeAppendableAudioStream(soundFreq, Audio::Mixer::FLAG_UNSIGNED);
_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, _audioStream);
// Read palette
_fd->read(_palette, 768);
updatePalette();
uint32 frameCount = 0;
uint16 chunkCount = 0;
uint32 soundSize = 0;
uint32 palChunkOfs = 0;
uint32 palSize = 0;
byte *frameData, *audioData, *soundData, *palData, *imageData;
bool firstTime = true;
uint32 frameNum;
uint16 width, height, cmdOffs, pixelOffs, maskOffs, lineSize;
// TODO: Sound can still be a little choppy. A bug in the decoder or -
// perhaps more likely - do we have to implement double buffering to
// get it to work well?
_audioStream = Audio::makeAppendableAudioStream(soundFreq, Audio::Mixer::FLAG_UNSIGNED);
while (!_abort && !_fd->eof()) {
@ -61,42 +68,41 @@ void PmvPlayer::play(const char *filename) {
if (_fd->eof())
break;
byte *frameData = new byte[chunkSize];
frameData = new byte[chunkSize];
_fd->read(frameData, chunkSize);
// Handle audio
byte *audioData = frameData + READ_LE_UINT32(frameData + 8) - 8;
audioData = frameData + READ_LE_UINT32(frameData + 8) - 8;
chunkSize = READ_LE_UINT16(audioData + 4);
uint16 chunkCount = READ_LE_UINT16(audioData + 6);
chunkCount = READ_LE_UINT16(audioData + 6);
if (chunkCount > 50) break; // FIXME: this is a hack
debug(2, "chunkCount = %d; chunkSize = %d\n", chunkCount, chunkSize);
uint32 soundSize = chunkCount * chunkSize;
byte *soundData = new byte[soundSize];
soundSize = chunkCount * chunkSize;
soundData = new byte[soundSize];
decompressSound(audioData + 8, soundData, chunkSize, chunkCount);
_audioStream->queueBuffer(soundData, soundSize);
// Handle palette
uint32 palChunkOfs = READ_LE_UINT32(frameData + 16);
palChunkOfs = READ_LE_UINT32(frameData + 16);
if (palChunkOfs) {
byte *palData = frameData + palChunkOfs - 8;
uint32 palSize = READ_LE_UINT32(palData + 4);
palData = frameData + palChunkOfs - 8;
palSize = READ_LE_UINT32(palData + 4);
decompressPalette(palData + 8, _palette, palSize);
updatePalette();
}
// Handle video
byte *imageData = frameData + READ_LE_UINT32(frameData + 12) - 8;
imageData = frameData + READ_LE_UINT32(frameData + 12) - 8;
uint32 frameNum = READ_LE_UINT32(frameData);
uint16 width = READ_LE_UINT16(imageData + 8);
uint16 height = READ_LE_UINT16(imageData + 10);
uint16 cmdOffs = READ_LE_UINT16(imageData + 12);
uint16 pixelOffs = READ_LE_UINT16(imageData + 16);
uint16 maskOffs = READ_LE_UINT16(imageData + 20);
uint16 lineSize = READ_LE_UINT16(imageData + 24);
frameNum = READ_LE_UINT32(frameData);
width = READ_LE_UINT16(imageData + 8);
height = READ_LE_UINT16(imageData + 10);
cmdOffs = READ_LE_UINT16(imageData + 12);
pixelOffs = READ_LE_UINT16(imageData + 16);
maskOffs = READ_LE_UINT16(imageData + 20);
lineSize = READ_LE_UINT16(imageData + 24);
debug(2, "width = %d; height = %d; cmdOffs = %04X; pixelOffs = %04X; maskOffs = %04X; lineSize = %d\n",
width, height, cmdOffs, pixelOffs, maskOffs, lineSize);
@ -107,14 +113,20 @@ void PmvPlayer::play(const char *filename) {
}
decompressImage(imageData, *_surface, cmdOffs, pixelOffs, maskOffs, lineSize, frameNum > 0);
if (firstTime) {
_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, _audioStream);
firstTime = false;
}
delete[] frameData;
updatePalette();
handleEvents();
updateScreen();
frameCount++;
delete[] frameData;
while (_mixer->getSoundElapsedTime(_audioStreamHandle) < frameCount * frameDelay) {
_system->delayMillis(10);
}

View File

@ -32,24 +32,35 @@ namespace Made {
void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount) {
int16 prevSample = 0;
int16 prevSample = 0, workSample = 0;
byte soundBuffer[1025];
byte soundBuffer3[1024];
int16 soundBuffer2[16];
byte deltaType, type;
uint16 workChunkSize, byteCount, bitCount;
byte bitMask, bitShift;
uint16 ofs = 0;
uint16 i = 0, l = 0;
byte val;
const int modeValues[3][4] = {
{ 2, 8, 0x01, 1},
{ 4, 4, 0x03, 2},
{16, 2, 0x0F, 4}
};
while (chunkCount--) {
deltaType = (*source) >> 6;
workChunkSize = chunkSize;
byte deltaType = (*source) >> 6;
uint16 workChunkSize = chunkSize;
if (deltaType == 1)
workChunkSize /= 2;
else if (deltaType == 2)
workChunkSize /= 4;
byte type = (*source++) & 0x0F;
type = (*source++) & 0x0F;
int16 workSample = prevSample;
workSample = prevSample;
switch (type) {
@ -64,27 +75,18 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
case 2:
case 3:
case 4:
{
byteCount = modeValues[type - 2][0];
bitCount = modeValues[type - 2][1];
bitMask = modeValues[type - 2][2];
bitShift = modeValues[type - 2][3];
ofs = 0;
const int modeValues[3][4] = {
{ 2, 8, 0x01, 1},
{ 4, 4, 0x03, 2},
{16, 2, 0x0F, 4}
};
uint16 byteCount = modeValues[type - 2][0];
uint16 bitCount = modeValues[type - 2][1];
byte bitMask = modeValues[type - 2][2];
byte bitShift = modeValues[type - 2][3];
uint16 ofs = 0;
for (uint16 i = 0; i < byteCount; i++)
for (i = 0; i < byteCount; i++)
soundBuffer2[i] = (*source++) * 2 - 128;
while (ofs < workChunkSize) {
byte val = *source++;
for (uint i = 0; i < bitCount; i++) {
val = *source++;
for (i = 0; i < bitCount; i++) {
workSample = CLIP<int16>(workSample + soundBuffer2[val & bitMask], -127, 127);
val >>= bitShift;
soundBuffer[ofs++] = workSample + 128;
@ -92,15 +94,12 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
}
break;
}
case 5:
{
for (uint16 i = 0; i < workChunkSize; i++)
for (i = 0; i < workChunkSize; i++)
soundBuffer[i] = *source++;
workSample = soundBuffer[workChunkSize - 1] - 128;
break;
}
default:
return;
@ -108,12 +107,12 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
}
if (deltaType == 1) {
for (uint16 i = 0; i < chunkSize - 1; i += 2) {
uint16 l = i / 2;
for (i = 0; i < chunkSize - 1; i += 2) {
l = i / 2;
soundBuffer3[i] = soundBuffer[l];
soundBuffer3[i + 1] = (soundBuffer[l + 1] + soundBuffer[l]) / 2;
}
for (uint16 i = 0; i < chunkSize; i++) {
for (i = 0; i < chunkSize; i++) {
soundBuffer[i] = soundBuffer3[i];
}
} else if (deltaType == 2) {