mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-05 17:57:14 +00:00
Performed some optimizations to the PMV player
svn-id: r31644
This commit is contained in:
parent
fb76c3eeed
commit
4e62a13a67
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user