aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
authorSven Hesse2008-03-07 00:16:37 +0000
committerSven Hesse2008-03-07 00:16:37 +0000
commit99d8cf695f49f1ded41712fac047dbf86054e8f8 (patch)
treef1818ab999c0f368470a93ea8cdb90686fc17da0 /engines/gob
parent130cfded751571069d16caff42baa709146ee501 (diff)
downloadscummvm-rg350-99d8cf695f49f1ded41712fac047dbf86054e8f8.tar.gz
scummvm-rg350-99d8cf695f49f1ded41712fac047dbf86054e8f8.tar.bz2
scummvm-rg350-99d8cf695f49f1ded41712fac047dbf86054e8f8.zip
Added support for RLE compressed frame data in VMDs
svn-id: r31044
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/coktelvideo.cpp69
-rw-r--r--engines/gob/coktelvideo.h2
2 files changed, 62 insertions, 9 deletions
diff --git a/engines/gob/coktelvideo.cpp b/engines/gob/coktelvideo.cpp
index 1668a123be..c6286fba3b 100644
--- a/engines/gob/coktelvideo.cpp
+++ b/engines/gob/coktelvideo.cpp
@@ -682,14 +682,14 @@ uint32 Imd::renderFrame(int16 left, int16 top, int16 right, int16 bottom) {
pixWritten = 0;
while (pixWritten < width) {
pixCount = *srcPtr++;
- if (pixCount & 0x80) { // data
+ if (pixCount & 0x80) { // Data
pixCount = MIN((pixCount & 0x7F) + 1, width - pixWritten);
memcpy(imdVidMem, srcPtr, pixCount);
pixWritten += pixCount;
imdVidMem += pixCount;
srcPtr += pixCount;
- } else { // "hole"
+ } else { // "Hole"
pixCount = (pixCount + 1) % 256;
pixWritten += pixCount;
imdVidMem += pixCount;
@@ -721,7 +721,7 @@ uint32 Imd::renderFrame(int16 left, int16 top, int16 right, int16 bottom) {
pixWritten = 0;
while (pixWritten < width) {
pixCount = *srcPtr++;
- if (pixCount & 0x80) { // data
+ if (pixCount & 0x80) { // Data
pixCount = MIN((pixCount & 0x7F) + 1, width - pixWritten);
memcpy(imdVidMem, srcPtr, pixCount);
memcpy(imdVidMem + sW, srcPtr, pixCount);
@@ -729,7 +729,7 @@ uint32 Imd::renderFrame(int16 left, int16 top, int16 right, int16 bottom) {
pixWritten += pixCount;
imdVidMem += pixCount;
srcPtr += pixCount;
- } else { // "hole"
+ } else { // "Hole"
pixCount = (pixCount + 1) % 256;
pixWritten += pixCount;
imdVidMem += pixCount;
@@ -747,7 +747,7 @@ void Imd::deLZ77(byte *dest, byte *src) {
int i;
byte buf[4370];
uint16 chunkLength;
- uint16 frameLength;
+ uint32 frameLength;
uint16 bufPos1;
uint16 bufPos2;
uint16 tmp;
@@ -1164,6 +1164,33 @@ CoktelVideo::State Vmd::processFrame(uint16 frame) {
return state;
}
+void Vmd::deRLE(byte *&srcPtr, byte *&destPtr, int16 len) {
+ srcPtr++;
+
+ if (len & 1)
+ *destPtr += *srcPtr++;
+
+ len >>= 1;
+
+ while (len > 0) {
+ uint8 tmp = *srcPtr++;
+ if (tmp & 0x80) { // Verbatim copy
+ tmp &= 0x7F;
+
+ memcpy(destPtr, srcPtr, tmp * 2);
+ destPtr += tmp * 2;
+ srcPtr += tmp * 2;
+ } else { // 2 bytes tmp times
+ for (int i = 0; i < tmp; i++) {
+ *destPtr++ = srcPtr[0];
+ *destPtr++ = srcPtr[1];
+ }
+ srcPtr += 2;
+ }
+ len -= tmp;
+ }
+}
+
uint32 Vmd::renderFrame(int16 left, int16 top, int16 right, int16 bottom) {
if (!_frameData || !_vidMem || (_width <= 0) || (_height <= 0))
return 0;
@@ -1197,14 +1224,14 @@ uint32 Vmd::renderFrame(int16 left, int16 top, int16 right, int16 bottom) {
pixWritten = 0;
while (pixWritten < width) {
pixCount = *srcPtr++;
- if (pixCount & 0x80) { // data
+ if (pixCount & 0x80) { // Data
pixCount = MIN((pixCount & 0x7F) + 1, width - pixWritten);
memcpy(imdVidMem, srcPtr, pixCount);
pixWritten += pixCount;
imdVidMem += pixCount;
srcPtr += pixCount;
- } else { // "hole"
+ } else { // "Hole"
pixCount = (pixCount + 1) % 256;
pixWritten += pixCount;
imdVidMem += pixCount;
@@ -1220,8 +1247,32 @@ uint32 Vmd::renderFrame(int16 left, int16 top, int16 right, int16 bottom) {
imdVidMem += sW;
}
} else if (type == 3) { // RLE block
- warning("Frame render method 3: RLE block");
- return 0;
+ for (int i = 0; i < height; i++) {
+ imdVidMemBak = imdVidMem;
+
+ pixWritten = 0;
+ while (pixWritten < width) {
+ pixCount = *srcPtr++;
+ if (pixCount & 0x80) {
+ pixCount = (pixCount & 0x7F) + 1;
+
+ if (*srcPtr != 0xFF) { // Normal copy
+ memcpy(imdVidMem, srcPtr, pixCount);
+ imdVidMem += pixCount;
+ srcPtr += pixCount;
+ } else
+ deRLE(srcPtr, imdVidMem, pixCount);
+
+ pixWritten += pixCount;
+ } else { // "Hole"
+ imdVidMem += pixCount + 1;
+ pixWritten += pixCount + 1;
+ }
+
+ }
+ imdVidMemBak += sW;
+ imdVidMem = imdVidMemBak;
+ }
} else {
warning("Unkown frame rendering method %d (0x%X)", type, type);
return 0;
diff --git a/engines/gob/coktelvideo.h b/engines/gob/coktelvideo.h
index 29a5c8896a..84271073f6 100644
--- a/engines/gob/coktelvideo.h
+++ b/engines/gob/coktelvideo.h
@@ -306,6 +306,8 @@ protected:
State processFrame(uint16 frame);
uint32 renderFrame(int16 left, int16 top, int16 right, int16 bottom);
+ void deRLE(byte *&srcPtr, byte *&destPtr, int16 len);
+
void emptySoundSlice(uint32 size);
void soundSlice8bit(uint32 size);
void soundSlice16bit(uint32 size, int16 &init);