aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Hesse2010-08-08 00:42:59 +0000
committerSven Hesse2010-08-08 00:42:59 +0000
commitfecbdf60a98d2cbadfc26b406b7076ae74424066 (patch)
treee081286c38ab1b7b8b512fad139dccf8d14c50c7
parent6172fe8ea7cf8046e5048e56a512ad0f847ac324 (diff)
downloadscummvm-rg350-fecbdf60a98d2cbadfc26b406b7076ae74424066.tar.gz
scummvm-rg350-fecbdf60a98d2cbadfc26b406b7076ae74424066.tar.bz2
scummvm-rg350-fecbdf60a98d2cbadfc26b406b7076ae74424066.zip
VIDEO/GOB: Implement IMD frame rendering
svn-id: r51867
-rw-r--r--engines/gob/videoplayer.cpp135
-rw-r--r--engines/gob/videoplayer.h11
-rw-r--r--graphics/video/coktel_decoder.cpp335
-rw-r--r--graphics/video/coktel_decoder.h13
4 files changed, 385 insertions, 109 deletions
diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index 174c3af506..fda5e4de2f 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -133,43 +133,44 @@ int VideoPlayer::openVideo(bool primary, const Common::String &file, Properties
if (!file.compareToIgnoreCase("SQ32-03.VMD"))
_woodruffCohCottWorkaround = true;
}
- }
- if (!(properties.flags & kFlagNoVideo) && (properties.sprite >= 0)) {
- bool ownSurf = (properties.sprite != Draw::kFrontSurface) && (properties.sprite != Draw::kBackSurface);
- bool screenSize = properties.flags & kFlagScreenSurface;
+ if (!(properties.flags & kFlagNoVideo) && (properties.sprite >= 0)) {
+ bool ownSurf = (properties.sprite != Draw::kFrontSurface) && (properties.sprite != Draw::kBackSurface);
+ bool screenSize = properties.flags & kFlagScreenSurface;
- if (ownSurf) {
- _vm->_draw->_spritesArray[properties.sprite] =
- _vm->_video->initSurfDesc(_vm->_global->_videoMode,
- screenSize ? _vm->_width : video->decoder->getWidth(),
- screenSize ? _vm->_height : video->decoder->getHeight(), 0);
- }
+ if (ownSurf) {
+ _vm->_draw->_spritesArray[properties.sprite] =
+ _vm->_video->initSurfDesc(_vm->_global->_videoMode,
+ screenSize ? _vm->_width : video->decoder->getWidth(),
+ screenSize ? _vm->_height : video->decoder->getHeight(), 0);
+ }
+
+ if (!_vm->_draw->_spritesArray[properties.sprite]) {
+ properties.sprite = -1;
+ video->surface.reset();
+ video->decoder->setSurfaceMemory();
+ video->decoder->setXY(0, 0);
+ } else {
+ video->surface = _vm->_draw->_spritesArray[properties.sprite];
+ video->decoder->setSurfaceMemory(video->surface->getVidMem(),
+ video->surface->getWidth(), video->surface->getHeight(), 1);
+
+ if (!ownSurf || (ownSurf && screenSize)) {
+ if ((properties.x >= 0) || (properties.y >= 0))
+ video->decoder->setXY((properties.x < 0) ? 0xFFFF : properties.x,
+ (properties.y < 0) ? 0xFFFF : properties.y);
+ else
+ video->decoder->setXY();
+ } else
+ video->decoder->setXY(0, 0);
+ }
- if (!_vm->_draw->_spritesArray[properties.sprite]) {
+ } else {
properties.sprite = -1;
video->surface.reset();
video->decoder->setSurfaceMemory();
video->decoder->setXY(0, 0);
- } else {
- video->surface = _vm->_draw->_spritesArray[properties.sprite];
- video->decoder->setSurfaceMemory(video->surface->getVidMem(),
- video->surface->getWidth(), video->surface->getHeight(), 1);
-
- if (!ownSurf || (ownSurf && screenSize)) {
- if ((properties.x >= 0) && (properties.y >= 0))
- video->decoder->setXY(properties.x, properties.y);
- else
- video->decoder->setXY();
- } else
- video->decoder->setXY(0, 0);
}
-
- } else {
- properties.sprite = -1;
- video->surface.reset();
- video->decoder->setSurfaceMemory();
- video->decoder->setXY(0, 0);
}
if (primary)
@@ -205,19 +206,16 @@ bool VideoPlayer::play(int slot, Properties &properties) {
if (properties.startFrame < 0)
properties.startFrame = video->decoder->getCurFrame() + 1;
if (properties.lastFrame < 0)
- properties.lastFrame = video->decoder->getFrameCount();
+ properties.lastFrame = video->decoder->getFrameCount() - 1;
if (properties.endFrame < 0)
properties.endFrame = properties.lastFrame;
if (properties.palFrame < 0)
properties.palFrame = properties.startFrame;
properties.startFrame--;
- properties.lastFrame--;
properties.endFrame--;
properties.palFrame--;
- properties.palCmd &= 0x3F;
-
if (primary) {
_vm->_draw->_showCursor = _noCursorSwitch ? 3 : 0;
@@ -229,9 +227,10 @@ bool VideoPlayer::play(int slot, Properties &properties) {
properties.canceled = false;
- while ((properties.startFrame != properties.lastFrame) && !properties.canceled) {
- if (!playFrame(slot, properties))
- return false;
+ while (properties.startFrame != properties.lastFrame) {
+ playFrame(slot, properties);
+ if (properties.canceled)
+ break;
properties.startFrame += backwards ? -1 : 1;
@@ -273,7 +272,7 @@ bool VideoPlayer::playFrame(int slot, Properties &properties) {
_vm->_draw->_applyPal = true;
if (properties.palCmd >= 4)
- ; // copyPalette(video, palStart, palEnd);
+ copyPalette(*video, properties.palStart, properties.palEnd);
}
if (modifiedPal && (properties.palCmd == 8) && (properties.sprite != Draw::kBackSurface))
@@ -312,16 +311,14 @@ bool VideoPlayer::playFrame(int slot, Properties &properties) {
_vm->_video->dirtyRectsAll();
}
- /*
- if ((state.flags & Graphics::CoktelDecoder::kStatePalette) && (palCmd > 1)) {
- copyPalette(video, palStart, palEnd);
+ if (video->decoder->hasPalette() && (properties.palCmd > 1)) {
+ copyPalette(*video, properties.palStart, properties.palEnd);
- if (!_backSurf)
+ if (properties.sprite != Draw::kBackSurface)
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
else
_vm->_draw->_applyPal = true;
}
- */
const Common::List<Common::Rect> &dirtyRects = video->decoder->getDirtyRects();
@@ -417,14 +414,6 @@ Common::String VideoPlayer::getFileName(int slot) const {
return video->fileName;
}
-uint16 VideoPlayer::getFlags(int slot) const {
- const Video *video = getVideoBySlot(slot);
- if (!video)
- return 0;
-
- return 0; // video->decoder->getFlags();
-}
-
uint32 VideoPlayer::getFrameCount(int slot) const {
const Video *video = getVideoBySlot(slot);
if (!video)
@@ -462,7 +451,7 @@ uint16 VideoPlayer::getDefaultX(int slot) const {
if (!video)
return 0;
- return 0; // video->decoder->getDefaultX();
+ return video->decoder->getDefaultX();
}
uint16 VideoPlayer::getDefaultY(int slot) const {
@@ -470,23 +459,7 @@ uint16 VideoPlayer::getDefaultY(int slot) const {
if (!video)
return 0;
- return 0; // video->decoder->getDefaultY();
-}
-
-uint32 VideoPlayer::getFeatures(int slot) const {
- const Video *video = getVideoBySlot(slot);
- if (!video)
- return 0;
-
- return 0; // video->decoder->getFeatures();
-}
-
-void VideoPlayer::getState(int slot) const {
- const Video *video = getVideoBySlot(slot);
- if (!video)
- return;
-
- return; // video->decoder->getState();
+ return video->decoder->getDefaultY();
}
bool VideoPlayer::hasExtraData(const Common::String &fileName, int slot) const {
@@ -715,12 +688,6 @@ void VideoPlayer::slotCopyFrame(int slot, byte *dest,
}
void VideoPlayer::slotCopyPalette(int slot, int16 palStart, int16 palEnd) {
-#if 0
- if ((slot < 0) || (slot >= kVideoSlotCount) || !_videoSlots[slot])
- return;
-
- //copyPalette(*(_videoSlots[slot]->getVideo()), palStart, palEnd);
-#endif
}
void VideoPlayer::slotWaitEndFrame(int slot, bool onlySound) {
@@ -741,31 +708,17 @@ void VideoPlayer::slotWaitEndFrame(int slot, bool onlySound) {
void VideoPlayer::slotSetDoubleMode(int slot, bool doubleMode) {
}
-void VideoPlayer::copyPalette(Graphics::CoktelDecoder &video, int16 palStart, int16 palEnd) {
- /*
- if (!(video.getFeatures() & Graphics::CoktelDecoder::kFeaturesPalette))
+void VideoPlayer::copyPalette(const Video &video, int16 palStart, int16 palEnd) {
+ if (!video.decoder->hasPalette())
return;
- */
if (palStart < 0)
palStart = 0;
if (palEnd < 0)
palEnd = 255;
- /*
memcpy(((char *)(_vm->_global->_pPaletteDesc->vgaPal)) + palStart * 3,
- video.getPalette() + palStart * 3,
- (palEnd - palStart + 1) * 3);
- */
-}
-
-void VideoPlayer::evalBgShading(Graphics::CoktelDecoder &video) {
- /*
- if (video.isSoundPlaying())
- _vm->_sound->bgShade();
- else
- _vm->_sound->bgUnshade();
- */
+ video.decoder->getPalette() + palStart * 3, (palEnd - palStart + 1) * 3);
}
} // End of namespace Gob
diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h
index 68e05dd322..f1245bca48 100644
--- a/engines/gob/videoplayer.h
+++ b/engines/gob/videoplayer.h
@@ -96,7 +96,7 @@ public:
void evaluateFlags(Properties &properties);
int openVideo(bool primary, const Common::String &file, Properties &properties);
- bool closeVideo(int slot);
+ bool closeVideo(int slot = 0);
bool play(int slot, Properties &properties);
@@ -104,16 +104,12 @@ public:
Common::String getFileName(int slot = 0) const;
- uint16 getFlags (int slot = 0) const;
uint32 getFrameCount (int slot = 0) const;
uint32 getCurrentFrame(int slot = 0) const;
uint16 getWidth (int slot = 0) const;
uint16 getHeight (int slot = 0) const;
uint16 getDefaultX (int slot = 0) const;
uint16 getDefaultY (int slot = 0) const;
- uint32 getFeatures (int slot = 0) const;
-
- void getState(int slot = 0) const;
bool hasExtraData(const Common::String &fileName, int slot = 0) const;
Common::MemoryReadStream *getExtraData(const Common::String &fileName, int slot = 0);
@@ -190,10 +186,7 @@ private:
void checkAbort(Video &video, Properties &properties);
void evalBgShading(Video &video);
- // Obsolete, to be deleted
-
- void copyPalette(Graphics::CoktelDecoder &video, int16 palStart = -1, int16 palEnd = -1);
- void evalBgShading(Graphics::CoktelDecoder &video);
+ void copyPalette(const Video &video, int16 palStart, int16 palEnd);
};
} // End of namespace Gob
diff --git a/graphics/video/coktel_decoder.cpp b/graphics/video/coktel_decoder.cpp
index ebb1c9492b..c8a934d5bb 100644
--- a/graphics/video/coktel_decoder.cpp
+++ b/graphics/video/coktel_decoder.cpp
@@ -121,6 +121,10 @@ const Common::List<Common::Rect> &CoktelDecoder::getDirtyRects() const {
return _dirtyRects;
}
+bool CoktelDecoder::hasPalette() const {
+ return (_features & kFeaturesPalette) != 0;
+}
+
bool CoktelDecoder::hasSound() const {
return _hasSound;
}
@@ -202,6 +206,235 @@ bool CoktelDecoder::hasDirtyPalette() const {
return (_features & kFeaturesPalette) && _paletteDirty;
}
+void CoktelDecoder::deLZ77(byte *dest, byte *src) {
+ int i;
+ byte buf[4370];
+ uint16 chunkLength;
+ uint32 frameLength;
+ uint16 bufPos1;
+ uint16 bufPos2;
+ uint16 tmp;
+ uint8 chunkBitField;
+ uint8 chunkCount;
+ bool mode;
+
+ frameLength = READ_LE_UINT32(src);
+ src += 4;
+
+ if ((READ_LE_UINT16(src) == 0x1234) && (READ_LE_UINT16(src + 2) == 0x5678)) {
+ src += 4;
+ bufPos1 = 273;
+ mode = 1; // 123Ch (cmp al, 12h)
+ } else {
+ bufPos1 = 4078;
+ mode = 0; // 275h (jnz +2)
+ }
+
+ memset(buf, 32, bufPos1);
+ chunkCount = 1;
+ chunkBitField = 0;
+
+ while (frameLength > 0) {
+ chunkCount--;
+ if (chunkCount == 0) {
+ tmp = *src++;
+ chunkCount = 8;
+ chunkBitField = tmp;
+ }
+ if (chunkBitField % 2) {
+ chunkBitField >>= 1;
+ buf[bufPos1] = *src;
+ *dest++ = *src++;
+ bufPos1 = (bufPos1 + 1) % 4096;
+ frameLength--;
+ continue;
+ }
+ chunkBitField >>= 1;
+
+ tmp = READ_LE_UINT16(src);
+ src += 2;
+ chunkLength = ((tmp & 0xF00) >> 8) + 3;
+
+ if ((mode && ((chunkLength & 0xFF) == 0x12)) ||
+ (!mode && (chunkLength == 0)))
+ chunkLength = *src++ + 0x12;
+
+ bufPos2 = (tmp & 0xFF) + ((tmp >> 4) & 0x0F00);
+ if (((tmp + chunkLength) >= 4096) ||
+ ((chunkLength + bufPos1) >= 4096)) {
+
+ for (i = 0; i < chunkLength; i++, dest++) {
+ *dest = buf[bufPos2];
+ buf[bufPos1] = buf[bufPos2];
+ bufPos1 = (bufPos1 + 1) % 4096;
+ bufPos2 = (bufPos2 + 1) % 4096;
+ }
+
+ } else if (((tmp + chunkLength) < bufPos1) ||
+ ((chunkLength + bufPos1) < bufPos2)) {
+
+ memcpy(dest, buf + bufPos2, chunkLength);
+ memmove(buf + bufPos1, buf + bufPos2, chunkLength);
+
+ dest += chunkLength;
+ bufPos1 += chunkLength;
+ bufPos2 += chunkLength;
+
+ } else {
+
+ for (i = 0; i < chunkLength; i++, dest++, bufPos1++, bufPos2++) {
+ *dest = buf[bufPos2];
+ buf[bufPos1] = buf[bufPos2];
+ }
+
+ }
+ frameLength -= chunkLength;
+
+ }
+}
+
+// A whole, completely filled block
+void CoktelDecoder::renderBlockWhole(const byte *src) {
+ Common::Rect &rect = _dirtyRects.back();
+ Common::Rect drawRect = rect;
+
+ drawRect.clip(_surface.w, _surface.h);
+
+ byte *dst = ((byte *) _surface.pixels) + (drawRect.top * _surface.pitch) + drawRect.left;
+ for (int i = 0; i < drawRect.height(); i++) {
+ memcpy(dst, src, drawRect.width());
+
+ src += rect.width();
+ dst += _surface.pitch;
+ }
+}
+
+// A quarter-wide whole, completely filled block
+void CoktelDecoder::renderBlockWhole4X(const byte *src) {
+ Common::Rect &rect = _dirtyRects.back();
+ Common::Rect drawRect = rect;
+
+ drawRect.clip(_surface.w, _surface.h);
+
+ byte *dst = ((byte *) _surface.pixels) + (drawRect.top * _surface.pitch) + drawRect.left;
+ for (int i = 0; i < drawRect.height(); i++) {
+ byte *dstRow = dst;
+ const byte *srcRow = src;
+
+ int16 count = drawRect.width();
+ while (count >= 0) {
+ memset(dstRow, *srcRow, MIN<int16>(count, 4));
+
+ count -= 4;
+ dstRow += 4;
+ srcRow += 1;
+ }
+
+ src += rect.width() / 4;
+ dst += _surface.pitch;
+ }
+}
+
+// A half-high whole, completely filled block
+void CoktelDecoder::renderBlockWhole2Y(const byte *src) {
+ warning("renderBlockWhole2Y");
+
+ Common::Rect &rect = _dirtyRects.back();
+ Common::Rect drawRect = rect;
+
+ drawRect.clip(_surface.w, _surface.h);
+
+ int16 height = drawRect.height();
+
+ byte *dst = ((byte *) _surface.pixels) + (drawRect.top * _surface.pitch) + drawRect.left;
+ while (height > 1) {
+ memcpy(dst , src, drawRect.width());
+ memcpy(dst + _surface.pitch, src, drawRect.width());
+
+ height -= 2;
+ src += rect.width();
+ dst += 2 * _surface.pitch;
+ }
+
+ if (height == 1)
+ memcpy(dst, src, drawRect.width());
+}
+
+// A sparse block
+void CoktelDecoder::renderBlockSparse(const byte *src) {
+ Common::Rect &rect = _dirtyRects.back();
+ Common::Rect drawRect = rect;
+
+ drawRect.clip(_surface.w, _surface.h);
+
+ byte *dst = ((byte *) _surface.pixels) + (drawRect.top * _surface.pitch) + drawRect.left;
+ for (int i = 0; i < drawRect.height(); i++) {
+ byte *dstRow = dst;
+ int16 pixWritten = 0;
+
+ while (pixWritten < rect.width()) {
+ int16 pixCount = *src++;
+
+ if (pixCount & 0x80) { // Data
+ int16 copyCount;
+
+ pixCount = MIN((pixCount & 0x7F) + 1, rect.width() - pixWritten);
+ copyCount = CLIP<int16>(drawRect.width() - pixWritten, 0, pixCount);
+ memcpy(dstRow, src, copyCount);
+
+ pixWritten += pixCount;
+ dstRow += pixCount;
+ src += pixCount;
+ } else { // "Hole"
+ pixWritten += pixCount + 1;
+ dstRow += pixCount + 1;
+ }
+
+ }
+
+ dst += _surface.pitch;
+ }
+}
+
+// A half-high sparse block
+void CoktelDecoder::renderBlockSparse2Y(const byte *src) {
+ warning("renderBlockSparse2Y");
+
+ Common::Rect &rect = _dirtyRects.back();
+ Common::Rect drawRect = rect;
+
+ drawRect.clip(_surface.w, _surface.h);
+
+ byte *dst = ((byte *) _surface.pixels) + (drawRect.top * _surface.pitch) + drawRect.left;
+ for (int i = 0; i < drawRect.height(); i += 2) {
+ byte *dstRow = dst;
+ int16 pixWritten = 0;
+
+ while (pixWritten < rect.width()) {
+ int16 pixCount = *src++;
+
+ if (pixCount & 0x80) { // Data
+ int16 copyCount;
+
+ pixCount = MIN((pixCount & 0x7F) + 1, rect.width() - pixWritten);
+ copyCount = CLIP<int16>(drawRect.width() - pixWritten, 0, pixCount);
+ memcpy(dstRow , src, pixCount);
+ memcpy(dstRow + _surface.pitch, src, pixCount);
+
+ pixWritten += pixCount;
+ dstRow += pixCount;
+ src += pixCount;
+ } else { // "Hole"
+ pixWritten += pixCount + 1;
+ dstRow += pixCount + 1;
+ }
+
+ }
+
+ dst += _surface.pitch;
+ }
+}
+
Common::Rational CoktelDecoder::getFrameRate() const {
return _frameRate;
}
@@ -471,7 +704,7 @@ bool IMDDecoder::seek(int32 frame, int whence, bool restart) {
return true;
} else {
- warning("Imd::seek(): Frame %d is not directly accessible", frame + 1);
+ warning("IMDDecoder::seek(): Frame %d is not directly accessible", frame + 1);
return false;
}
@@ -482,6 +715,37 @@ bool IMDDecoder::seek(int32 frame, int whence, bool restart) {
return true;
}
+void IMDDecoder::setXY(uint16 x, uint16 y) {
+ // Adjusting the standard coordinates
+ if (_stdX != -1) {
+ if (x != 0xFFFF)
+ _stdX = _stdX - _x + x;
+ if (y != 0xFFFF)
+ _stdY = _stdY - _y + y;
+ }
+
+ // Going through the coordinate table as well
+ if (_frameCoords) {
+ for (uint32 i = 0; i < _frameCount; i++) {
+ if (_frameCoords[i].left != -1) {
+ if (x != 0xFFFF) {
+ _frameCoords[i].left = _frameCoords[i].left - _x + x;
+ _frameCoords[i].right = _frameCoords[i].right - _x + x;
+ }
+ if (y != 0xFFFF) {
+ _frameCoords[i].top = _frameCoords[i].top - _y + y;
+ _frameCoords[i].bottom = _frameCoords[i].bottom - _y + y;
+ }
+ }
+ }
+ }
+
+ if (x != 0xFFFF)
+ _x = x;
+ if (y != 0xFFFF)
+ _y = y;
+}
+
bool IMDDecoder::load(Common::SeekableReadStream &stream) {
close();
@@ -559,7 +823,7 @@ bool IMDDecoder::loadCoordinates() {
if (_version >= 3) {
uint16 count = _stream->readUint16LE();
if (count > 1) {
- warning("IMD: More than one standard coordinate quad found (%d)", count );
+ warning("IMDDecoder::loadCoordinates(): More than one standard coordinate quad found (%d)", count);
return false;
}
@@ -733,7 +997,6 @@ Surface *IMDDecoder::decodeNextFrame() {
createSurface();
processFrame();
- renderFrame();
if (_curFrame == 0)
_startTime = g_system->getMillis();
@@ -753,8 +1016,6 @@ void IMDDecoder::processFrame() {
bool startSound = false;
do {
- calcFrameCoords(_curFrame);
-
cmd = _stream->readUint16LE();
if ((cmd & kCommandBreakMask) == kCommandBreak) {
@@ -819,12 +1080,15 @@ void IMDDecoder::processFrame() {
}
} else if (cmd == kCommandVideoData) {
+ calcFrameCoords(_curFrame);
+
videoData(_stream->readUint32LE() + 2);
- } else if (cmd != 0)
+ } else if (cmd != 0) {
+ calcFrameCoords(_curFrame);
+
videoData(cmd + 2);
- else
- _dirtyRects.pop_back();
+ }
} while (hasNextCmd);
@@ -862,7 +1126,60 @@ void IMDDecoder::videoData(uint32 size) {
}
void IMDDecoder::renderFrame() {
- // TODO
+ if (_dirtyRects.empty())
+ return;
+
+ Common::Rect &rect = _dirtyRects.back();
+
+ rect.clip(Common::Rect(_x, _y, _x + _width, _y + _height));
+ if (!rect.isValidRect() || rect.isEmpty()) {
+ _dirtyRects.pop_back();
+ return;
+ }
+
+ byte *dataPtr = _frameData;
+
+ uint8 type = *dataPtr++;
+
+ if (type & 0x10) { // Palette data
+ // One byte index
+ int index = *dataPtr++;
+ // 16 entries with each 3 bytes (RGB)
+ memcpy(_palette + index * 3, dataPtr, MIN((255 - index) * 3, 48));
+
+ dataPtr += 48;
+ type ^= 0x10;
+
+ _paletteDirty = true;
+ }
+
+ if (type & 0x80) {
+ // Frame data is compressed
+
+ type &= 0x7F;
+
+ if ((type == 2) && (rect.width() == _surface.w)) {
+ // Directly uncompress onto the video surface
+ deLZ77((byte *) _surface.pixels, dataPtr);
+ return;
+ }
+
+ deLZ77(_videoBuffer, dataPtr);
+
+ dataPtr = _videoBuffer;
+ }
+
+ // Evaluate the block type
+ if (type == 0x01)
+ renderBlockSparse (dataPtr);
+ else if (type == 0x02)
+ renderBlockWhole (dataPtr);
+ else if (type == 0x42)
+ renderBlockWhole4X (dataPtr);
+ else if ((type & 0x0F) == 0x02)
+ renderBlockWhole2Y (dataPtr);
+ else
+ renderBlockSparse2Y(dataPtr);
}
void IMDDecoder::nextSoundSlice(bool hasNextCmd) {
diff --git a/graphics/video/coktel_decoder.h b/graphics/video/coktel_decoder.h
index 1736132cf4..0464b8e31b 100644
--- a/graphics/video/coktel_decoder.h
+++ b/graphics/video/coktel_decoder.h
@@ -84,6 +84,8 @@ public:
/** Return a list of rectangles that changed in the last frame. */
const Common::List<Common::Rect> &getDirtyRects() const;
+ bool hasPalette() const;
+
bool hasSound() const;
bool isSoundEnabled() const;
bool isSoundPlaying() const;
@@ -159,8 +161,17 @@ protected:
void createSurface();
void freeSurface();
+ void deLZ77(byte *dest, byte *src);
+
+ void renderBlockWhole (const byte *src);
+ void renderBlockWhole4X (const byte *src);
+ void renderBlockWhole2Y (const byte *src);
+ void renderBlockSparse (const byte *src);
+ void renderBlockSparse2Y(const byte *src);
+
inline void unsignedToSigned(byte *buffer, int length);
+public:
// FixedRateVideoDecoder interface
Common::Rational getFrameRate() const;
};
@@ -202,6 +213,8 @@ public:
bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
+ void setXY(uint16 x, uint16 y);
+
// VideoDecoder interface
bool load(Common::SeekableReadStream &stream);