From 506c1e7d85773b2fe7e8a8d69edde7fc8f88fe10 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Aug 2010 00:59:58 +0000 Subject: VIDEO: Change the CoktelDecoder::renderBlock*'s signatures Change CoktelDecoder::renderBlock*() and IMDDecoder::renderFrame() to receive a Common::Rect instead of mucking about with _dirtyRects. svn-id: r51904 --- graphics/video/coktel_decoder.cpp | 188 +++++++++++++++++++------------------- graphics/video/coktel_decoder.h | 17 ++-- 2 files changed, 100 insertions(+), 105 deletions(-) diff --git a/graphics/video/coktel_decoder.cpp b/graphics/video/coktel_decoder.cpp index 8550325a29..567a51f8d1 100644 --- a/graphics/video/coktel_decoder.cpp +++ b/graphics/video/coktel_decoder.cpp @@ -342,34 +342,32 @@ void CoktelDecoder::deLZ77(byte *dest, byte *src) { } // A whole, completely filled block -void CoktelDecoder::renderBlockWhole(const byte *src) { - Common::Rect &rect = _dirtyRects.back(); - Common::Rect drawRect = rect; +void CoktelDecoder::renderBlockWhole(const byte *src, Common::Rect &rect) { + Common::Rect srcRect = rect; - drawRect.clip(_surface.w, _surface.h); + rect.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()); + byte *dst = (byte *)_surface.pixels + (rect.top * _surface.pitch) + rect.left; + for (int i = 0; i < rect.height(); i++) { + memcpy(dst, src, rect.width()); - src += rect.width(); + src += srcRect.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; +void CoktelDecoder::renderBlockWhole4X(const byte *src, Common::Rect &rect) { + Common::Rect srcRect = rect; - drawRect.clip(_surface.w, _surface.h); + rect.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 *dst = (byte *)_surface.pixels + (rect.top * _surface.pitch) + rect.left; + for (int i = 0; i < rect.height(); i++) { byte *dstRow = dst; const byte *srcRow = src; - int16 count = drawRect.width(); + int16 count = rect.width(); while (count >= 0) { memset(dstRow, *srcRow, MIN(count, 4)); @@ -378,54 +376,52 @@ void CoktelDecoder::renderBlockWhole4X(const byte *src) { srcRow += 1; } - src += rect.width() / 4; + src += srcRect.width() / 4; dst += _surface.pitch; } } // A half-high whole, completely filled block -void CoktelDecoder::renderBlockWhole2Y(const byte *src) { - Common::Rect &rect = _dirtyRects.back(); - Common::Rect drawRect = rect; +void CoktelDecoder::renderBlockWhole2Y(const byte *src, Common::Rect &rect) { + Common::Rect srcRect = rect; - drawRect.clip(_surface.w, _surface.h); + rect.clip(_surface.w, _surface.h); - int16 height = drawRect.height(); + int16 height = rect.height(); - byte *dst = (byte *)_surface.pixels + (drawRect.top * _surface.pitch) + drawRect.left; + byte *dst = (byte *)_surface.pixels + (rect.top * _surface.pitch) + rect.left; while (height > 1) { - memcpy(dst , src, drawRect.width()); - memcpy(dst + _surface.pitch, src, drawRect.width()); + memcpy(dst , src, rect.width()); + memcpy(dst + _surface.pitch, src, rect.width()); height -= 2; - src += rect.width(); + src += srcRect.width(); dst += 2 * _surface.pitch; } if (height == 1) - memcpy(dst, src, drawRect.width()); + memcpy(dst, src, rect.width()); } // A sparse block -void CoktelDecoder::renderBlockSparse(const byte *src) { - Common::Rect &rect = _dirtyRects.back(); - Common::Rect drawRect = rect; +void CoktelDecoder::renderBlockSparse(const byte *src, Common::Rect &rect) { + Common::Rect srcRect = rect; - drawRect.clip(_surface.w, _surface.h); + rect.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 *dst = (byte *)_surface.pixels + (rect.top * _surface.pitch) + rect.left; + for (int i = 0; i < rect.height(); i++) { byte *dstRow = dst; int16 pixWritten = 0; - while (pixWritten < rect.width()) { + while (pixWritten < srcRect.width()) { int16 pixCount = *src++; if (pixCount & 0x80) { // Data int16 copyCount; - pixCount = MIN((pixCount & 0x7F) + 1, rect.width() - pixWritten); - copyCount = CLIP(drawRect.width() - pixWritten, 0, pixCount); + pixCount = MIN((pixCount & 0x7F) + 1, srcRect.width() - pixWritten); + copyCount = CLIP(rect.width() - pixWritten, 0, pixCount); memcpy(dstRow, src, copyCount); pixWritten += pixCount; @@ -443,27 +439,26 @@ void CoktelDecoder::renderBlockSparse(const byte *src) { } // A half-high sparse block -void CoktelDecoder::renderBlockSparse2Y(const byte *src) { +void CoktelDecoder::renderBlockSparse2Y(const byte *src, Common::Rect &rect) { warning("renderBlockSparse2Y"); - Common::Rect &rect = _dirtyRects.back(); - Common::Rect drawRect = rect; + Common::Rect srcRect = rect; - drawRect.clip(_surface.w, _surface.h); + rect.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 *dst = (byte *)_surface.pixels + (rect.top * _surface.pitch) + rect.left; + for (int i = 0; i < rect.height(); i += 2) { byte *dstRow = dst; int16 pixWritten = 0; - while (pixWritten < rect.width()) { + while (pixWritten < srcRect.width()) { int16 pixCount = *src++; if (pixCount & 0x80) { // Data int16 copyCount; - pixCount = MIN((pixCount & 0x7F) + 1, rect.width() - pixWritten); - copyCount = CLIP(drawRect.width() - pixWritten, 0, pixCount); + pixCount = MIN((pixCount & 0x7F) + 1, srcRect.width() - pixWritten); + copyCount = CLIP(rect.width() - pixWritten, 0, pixCount); memcpy(dstRow , src, pixCount); memcpy(dstRow + _surface.pitch, src, pixCount); @@ -1124,14 +1119,25 @@ void IMDDecoder::processFrame() { } } else if (cmd == kCommandVideoData) { - calcFrameCoords(_curFrame); - videoData(_stream->readUint32LE() + 2); + _frameDataLen = _stream->readUint32LE() + 2; + _stream->read(_frameData, _frameDataLen); + + Common::Rect rect = calcFrameCoords(_curFrame); + + if (renderFrame(rect)) + _dirtyRects.push_back(rect); } else if (cmd != 0) { - calcFrameCoords(_curFrame); - videoData(cmd + 2); + _frameDataLen = cmd + 2; + _stream->read(_frameData, _frameDataLen); + + Common::Rect rect = calcFrameCoords(_curFrame); + + if (renderFrame(rect)) + _dirtyRects.push_back(rect); + } } while (hasNextCmd); @@ -1152,64 +1158,52 @@ void IMDDecoder::processFrame() { } -void IMDDecoder::calcFrameCoords(uint32 frame) { - int16 left, top, right, bottom; +Common::Rect IMDDecoder::calcFrameCoords(uint32 frame) { + Common::Rect rect; if (frame == 0) { // First frame is always a full "keyframe" - left = _x; - top = _y; - right = _x + _width; - bottom = _y + _height; + rect.left = _x; + rect.top = _y; + rect.right = _x + _width; + rect.bottom = _y + _height; } else if (_frameCoords && ((_frameCoords[frame].left != -1))) { // We have frame coordinates for that frame - left = _frameCoords[frame].left; - top = _frameCoords[frame].top; - right = _frameCoords[frame].right + 1; - bottom = _frameCoords[frame].bottom + 1; + rect.left = _frameCoords[frame].left; + rect.top = _frameCoords[frame].top; + rect.right = _frameCoords[frame].right + 1; + rect.bottom = _frameCoords[frame].bottom + 1; } else if (_stdX != -1) { // We have standard coordinates - left = _stdX; - top = _stdY; - right = _stdX + _stdWidth; - bottom = _stdY + _stdHeight; + rect.left = _stdX; + rect.top = _stdY; + rect.right = _stdX + _stdWidth; + rect.bottom = _stdY + _stdHeight; } else { // Otherwise, it must be a full "keyframe" - left = _x; - top = _y; - right = _x + _width; - bottom = _y + _height; + rect.left = _x; + rect.top = _y; + rect.right = _x + _width; + rect.bottom = _y + _height; } - _dirtyRects.push_back(Common::Rect(left, top, right, bottom)); + return rect; } -void IMDDecoder::videoData(uint32 size) { - _stream->read(_frameData, size); - _frameDataLen = size; - - renderFrame(); -} - -void IMDDecoder::renderFrame() { - if (_dirtyRects.empty()) - // Nothing to do - return; - - // The area for the frame - Common::Rect &rect = _dirtyRects.back(); +bool IMDDecoder::renderFrame(Common::Rect &rect) { + if (!rect.isValidRect()) + // Invalid rendering area + return false; - // Clip it by the video's visible area + // Clip the rendering area to the video's visible area rect.clip(Common::Rect(_x, _y, _x + _width, _y + _height)); - if (!rect.isValidRect() || rect.isEmpty()) { + if (!rect.isValidRect() || rect.isEmpty()) // Result is empty => nothing to do - _dirtyRects.pop_back(); - return; - } + return false; byte *dataPtr = _frameData; @@ -1237,7 +1231,7 @@ void IMDDecoder::renderFrame() { if ((type == 2) && (rect.width() == _surface.w) && (_x == 0)) { // Directly uncompress onto the video surface deLZ77((byte *)_surface.pixels + (_y * _surface.pitch), dataPtr); - return; + return true; } deLZ77(_videoBuffer, dataPtr); @@ -1247,15 +1241,17 @@ void IMDDecoder::renderFrame() { // Evaluate the block type if (type == 0x01) - renderBlockSparse (dataPtr); + renderBlockSparse (dataPtr, rect); else if (type == 0x02) - renderBlockWhole (dataPtr); + renderBlockWhole (dataPtr, rect); else if (type == 0x42) - renderBlockWhole4X (dataPtr); + renderBlockWhole4X (dataPtr, rect); else if ((type & 0x0F) == 0x02) - renderBlockWhole2Y (dataPtr); + renderBlockWhole2Y (dataPtr, rect); else - renderBlockSparse2Y(dataPtr); + renderBlockSparse2Y(dataPtr, rect); + + return true; } void IMDDecoder::nextSoundSlice(bool hasNextCmd) { @@ -1902,9 +1898,9 @@ void VMDDecoder::processFrame() { _stream->read(_frameData, size); _frameDataLen = size; - int16 l = part.left, t = part.top, r = part.right, b = part.bottom; - if (renderFrame(l, t, r, b)) - _dirtyRects.push_back(Common::Rect(l, t, r + 1, b + 1)); + Common::Rect rect(part.left, part.top, part.right + 1, part.bottom + 1); + if (renderFrame(rect)) + _dirtyRects.push_back(rect); } else if (part.type == kPartTypeSeparator) { @@ -1951,7 +1947,7 @@ void VMDDecoder::processFrame() { } } -bool VMDDecoder::renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom) { +bool VMDDecoder::renderFrame(Common::Rect &rect) { // TODO return false; diff --git a/graphics/video/coktel_decoder.h b/graphics/video/coktel_decoder.h index 4f52a34a40..f713f39470 100644 --- a/graphics/video/coktel_decoder.h +++ b/graphics/video/coktel_decoder.h @@ -188,11 +188,11 @@ protected: void deLZ77(byte *dest, byte *src); // Block rendering - 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); + void renderBlockWhole (const byte *src, Common::Rect &rect); + void renderBlockWhole4X (const byte *src, Common::Rect &rect); + void renderBlockWhole2Y (const byte *src, Common::Rect &rect); + void renderBlockSparse (const byte *src, Common::Rect &rect); + void renderBlockSparse2Y(const byte *src, Common::Rect &rect); // Sound helper functions inline void unsignedToSigned(byte *buffer, int length); @@ -320,11 +320,10 @@ private: // Frame decoding void processFrame(); - void calcFrameCoords(uint32 frame); + Common::Rect calcFrameCoords(uint32 frame); // Video - void videoData(uint32 size); - void renderFrame(); + bool renderFrame(Common::Rect &rect); // Sound void nextSoundSlice(bool hasNextCmd); @@ -461,7 +460,7 @@ private: void processFrame(); // Video - bool renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom); + bool renderFrame(Common::Rect &rect); // Sound void emptySoundSlice (uint32 size); -- cgit v1.2.3