aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Haisch2008-05-19 19:34:55 +0000
committerBenjamin Haisch2008-05-19 19:34:55 +0000
commitcefff90ac61e95641950ae694e3334c1c344c32d (patch)
tree9e476c7843f854757fdcf7794bcee7ae6c4b6422
parent460296f3602d35779664f2776cce7365829ccca8 (diff)
downloadscummvm-rg350-cefff90ac61e95641950ae694e3334c1c344c32d.tar.gz
scummvm-rg350-cefff90ac61e95641950ae694e3334c1c344c32d.tar.bz2
scummvm-rg350-cefff90ac61e95641950ae694e3334c1c344c32d.zip
RtZ: Fixed bug which caused PMV videos to look odd (noticeable in the intro movie) and optimized frame decompression code.
svn-id: r32182
-rw-r--r--engines/made/graphics.cpp111
-rw-r--r--engines/made/graphics.h1
-rw-r--r--engines/made/pmvplayer.cpp30
3 files changed, 129 insertions, 13 deletions
diff --git a/engines/made/graphics.cpp b/engines/made/graphics.cpp
index 081621ef18..76b39ed43a 100644
--- a/engines/made/graphics.cpp
+++ b/engines/made/graphics.cpp
@@ -47,7 +47,6 @@ void decompressImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, u
byte *destPtr = (byte*)surface.getBasePtr(0, 0);
- //byte lineBuf[320 * 4];
byte lineBuf[640 * 4];
byte bitBuf[40];
@@ -149,4 +148,114 @@ void decompressImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, u
}
+void decompressMovieImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, uint16 pixelOffs, uint16 maskOffs, uint16 lineSize) {
+
+ uint16 width = surface.w;
+ uint16 height = surface.h;
+ uint16 bx = 0, by = 0, bw = ((width + 3) / 4) * 4;
+
+ byte *cmdBuffer = source + cmdOffs;
+ byte *maskBuffer = source + maskOffs;
+ byte *pixelBuffer = source + pixelOffs;
+
+ byte *destPtr = (byte*)surface.getBasePtr(0, 0);
+
+ byte bitBuf[40];
+
+ int bitBufLastOfs = (((lineSize + 1) >> 1) << 1) - 2;
+ int bitBufLastCount = ((width + 3) >> 2) & 7;
+ if (bitBufLastCount == 0)
+ bitBufLastCount = 8;
+
+ debug(1, "width = %d; bw = %d", width, bw);
+
+ while (height > 0) {
+
+ int drawDestOfs = 0;
+
+ memcpy(bitBuf, cmdBuffer, lineSize);
+ cmdBuffer += lineSize;
+
+ for (uint16 bitBufOfs = 0; bitBufOfs < lineSize; bitBufOfs += 2) {
+
+ uint16 bits = READ_LE_UINT16(&bitBuf[bitBufOfs]);
+
+ int bitCount;
+ if (bitBufOfs == bitBufLastOfs)
+ bitCount = bitBufLastCount;
+ else
+ bitCount = 8;
+
+ for (int curCmd = 0; curCmd < bitCount; curCmd++) {
+ uint cmd = bits & 3;
+ bits >>= 2;
+
+ byte pixels[4], block[16];
+ uint32 mask;
+
+ switch (cmd) {
+
+ case 0:
+ pixels[0] = *pixelBuffer++;
+ for (int i = 0; i < 16; i++)
+ block[i] = pixels[0];
+ break;
+
+ case 1:
+ pixels[0] = *pixelBuffer++;
+ pixels[1] = *pixelBuffer++;
+ mask = READ_LE_UINT16(maskBuffer);
+ maskBuffer += 2;
+ for (int i = 0; i < 16; i++) {
+ block[i] = pixels[mask & 1];
+ mask >>= 1;
+ }
+ break;
+
+ case 2:
+ pixels[0] = *pixelBuffer++;
+ pixels[1] = *pixelBuffer++;
+ pixels[2] = *pixelBuffer++;
+ pixels[3] = *pixelBuffer++;
+ mask = READ_LE_UINT32(maskBuffer);
+ maskBuffer += 4;
+ for (int i = 0; i < 16; i++) {
+ block[i] = pixels[mask & 3];
+ mask >>= 2;
+ }
+ break;
+
+ case 3:
+ break;
+
+ }
+
+ if (cmd != 3) {
+ uint16 blockPos = 0;
+ uint32 maxW = MIN(4, surface.w - bx);
+ uint32 maxH = (MIN(4, surface.h - by) + by) * width;
+ for (uint32 yc = by * width; yc < maxH; yc += width) {
+ for (uint32 xc = 0; xc < maxW; xc++) {
+ destPtr[(bx + xc) + yc] = block[xc + blockPos];
+ }
+ blockPos += 4;
+ }
+ }
+
+ bx += 4;
+ if (bx >= bw) {
+ bx = 0;
+ by += 4;
+ }
+
+ }
+
+ }
+
+ height -= 4;
+
+ }
+
+}
+
} // End of namespace Made
diff --git a/engines/made/graphics.h b/engines/made/graphics.h
index 3c56bb4231..31c747a89b 100644
--- a/engines/made/graphics.h
+++ b/engines/made/graphics.h
@@ -34,6 +34,7 @@
namespace Made {
void decompressImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, uint16 pixelOffs, uint16 maskOffs, uint16 lineSize, bool deltaFrame = false);
+void decompressMovieImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, uint16 pixelOffs, uint16 maskOffs, uint16 lineSize);
} // End of namespace Made
diff --git a/engines/made/pmvplayer.cpp b/engines/made/pmvplayer.cpp
index db56235a67..8180758d61 100644
--- a/engines/made/pmvplayer.cpp
+++ b/engines/made/pmvplayer.cpp
@@ -74,7 +74,7 @@ void PmvPlayer::play(const char *filename) {
uint32 frameCount = 0;
uint16 chunkCount = 0;
uint32 soundSize = 0;
- uint32 palChunkOfs = 0;
+ uint32 soundChunkOfs = 0, palChunkOfs = 0;
uint32 palSize = 0;
byte *frameData, *audioData, *soundData, *palData, *imageData;
bool firstTime = true;
@@ -100,23 +100,29 @@ void PmvPlayer::play(const char *filename) {
frameData = new byte[chunkSize];
_fd->read(frameData, chunkSize);
+
+ soundChunkOfs = READ_LE_UINT32(frameData + 8);
+ palChunkOfs = READ_LE_UINT32(frameData + 16);
// Handle audio
- audioData = frameData + READ_LE_UINT32(frameData + 8) - 8;
- chunkSize = READ_LE_UINT16(audioData + 4);
- chunkCount = READ_LE_UINT16(audioData + 6);
+ if (soundChunkOfs) {
+
+ audioData = frameData + soundChunkOfs - 8;
+ chunkSize = READ_LE_UINT16(audioData + 4);
+ chunkCount = READ_LE_UINT16(audioData + 6);
- if (chunkCount > 50) break; // FIXME: this is a hack
+ debug(1, "chunkCount = %d; chunkSize = %d; total = %d\n", chunkCount, chunkSize, chunkCount * chunkSize);
- debug(1, "chunkCount = %d; chunkSize = %d; total = %d\n", chunkCount, chunkSize, chunkCount * chunkSize);
+ if (chunkCount > 50) break; // FIXME: this is a hack
- soundSize = chunkCount * chunkSize;
- soundData = new byte[soundSize];
- decompressSound(audioData + 8, soundData, chunkSize, chunkCount);
- _audioStream->queueBuffer(soundData, soundSize);
+ soundSize = chunkCount * chunkSize;
+ soundData = new byte[soundSize];
+ decompressSound(audioData + 8, soundData, chunkSize, chunkCount);
+ _audioStream->queueBuffer(soundData, soundSize);
+
+ }
// Handle palette
- palChunkOfs = READ_LE_UINT32(frameData + 16);
if (palChunkOfs) {
palData = frameData + palChunkOfs - 8;
palSize = READ_LE_UINT32(palData + 4);
@@ -143,7 +149,7 @@ void PmvPlayer::play(const char *filename) {
_surface->create(width, height, 1);
}
- decompressImage(imageData, *_surface, cmdOffs, pixelOffs, maskOffs, lineSize, frameNum > 0);
+ decompressMovieImage(imageData, *_surface, cmdOffs, pixelOffs, maskOffs, lineSize);
if (firstTime) {
_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, _audioStream);