aboutsummaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
authorSven Hesse2010-08-08 00:59:58 +0000
committerSven Hesse2010-08-08 00:59:58 +0000
commit506c1e7d85773b2fe7e8a8d69edde7fc8f88fe10 (patch)
treed74f6f5064a3ac98fdb9b878033b7fd17b23d4a6 /graphics
parent6d31b1768500f03734d4e24dc13d088215071bde (diff)
downloadscummvm-rg350-506c1e7d85773b2fe7e8a8d69edde7fc8f88fe10.tar.gz
scummvm-rg350-506c1e7d85773b2fe7e8a8d69edde7fc8f88fe10.tar.bz2
scummvm-rg350-506c1e7d85773b2fe7e8a8d69edde7fc8f88fe10.zip
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
Diffstat (limited to 'graphics')
-rw-r--r--graphics/video/coktel_decoder.cpp188
-rw-r--r--graphics/video/coktel_decoder.h17
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<int16>(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<int16>(drawRect.width() - pixWritten, 0, pixCount);
+ pixCount = MIN((pixCount & 0x7F) + 1, srcRect.width() - pixWritten);
+ copyCount = CLIP<int16>(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<int16>(drawRect.width() - pixWritten, 0, pixCount);
+ pixCount = MIN((pixCount & 0x7F) + 1, srcRect.width() - pixWritten);
+ copyCount = CLIP<int16>(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);