aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/video.cpp
diff options
context:
space:
mode:
authorSven Hesse2010-09-30 13:02:16 +0000
committerSven Hesse2010-09-30 13:02:16 +0000
commit51fd528fe56e00466255d54e1e71b19f34729bfd (patch)
tree4ced8883bebd5ca93eb4aeb315a496c535e87c78 /engines/gob/video.cpp
parent38e506004101edb6460c695fc62754fb9e951883 (diff)
downloadscummvm-rg350-51fd528fe56e00466255d54e1e71b19f34729bfd.tar.gz
scummvm-rg350-51fd528fe56e00466255d54e1e71b19f34729bfd.tar.bz2
scummvm-rg350-51fd528fe56e00466255d54e1e71b19f34729bfd.zip
GOB: Change all drawing to use class Surface
svn-id: r52947
Diffstat (limited to 'engines/gob/video.cpp')
-rw-r--r--engines/gob/video.cpp331
1 files changed, 87 insertions, 244 deletions
diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp
index 6d2636d067..1de25cb594 100644
--- a/engines/gob/video.cpp
+++ b/engines/gob/video.cpp
@@ -89,81 +89,66 @@ uint16 Font::getCharCount() const {
return _endItem - _startItem + 1;
}
-uint8 Font::getFirstChar() const {
- return _startItem;
-}
-
-uint8 Font::getLastChar() const {
- return _endItem;
-}
-
-uint8 Font::getCharSize() const {
- return _itemSize;
-}
-
bool Font::isMonospaced() const {
return _charWidths == 0;
}
-const byte *Font::getCharData(uint8 c) const {
- if (_endItem == 0) {
- warning("Font::getCharData(): _endItem == 0");
- return 0;
+void Font::drawLetter(Surface &surf, uint8 c, uint16 x, uint16 y,
+ uint32 color1, uint32 color2, bool transp) const {
+
+ uint16 data;
+
+ const byte *src = getCharData(c);
+ if (!src) {
+ warning("Font::drawLetter(): getCharData() == 0");
+ return;
}
- if ((c < _startItem) || (c > _endItem))
- return 0;
+ Pixel dst = surf.get(x, y);
- return _data + (c - _startItem) * _itemSize;
-}
+ int nWidth = _itemWidth;
+ if (nWidth & 7)
+ nWidth = (nWidth & 0xF8) + 8;
+ nWidth >>= 3;
-SurfaceDesc::SurfaceDesc(int16 vidMode, int16 width, int16 height,
- byte *vidMem) : _width(width), _height(height) {
+ for (int i = 0; i < _itemHeight; i++) {
+ int width = _itemWidth;
- if (vidMem) {
- _vidMode = vidMode;
- _ownVidMem = false;
- _vidMem = vidMem;
- } else {
- _vidMode = vidMode;
- _ownVidMem = true;
- _vidMem = new byte[width * height];
- assert(_vidMem);
- memset(_vidMem, 0, width * height);
- }
-}
+ for (int k = 0; k < nWidth; k++) {
-void SurfaceDesc::setVidMem(byte *vidMem) {
- assert(vidMem);
+ data = *src++;
+ for (int j = 0; j < MIN(8, width); j++) {
+ if (data & 0x80)
+ dst.set(color1);
+ else if (!transp)
+ dst.set(color2);
- if (hasOwnVidMem())
- delete[] _vidMem;
+ dst++;
+ data <<= 1;
+ }
- _ownVidMem = false;
- _vidMem = vidMem;
-}
+ width -= 8;
-void SurfaceDesc::resize(int16 width, int16 height) {
- if (hasOwnVidMem())
- delete[] _vidMem;
+ }
- _width = width;
- _height = height;
- _ownVidMem = true;
- _vidMem = new byte[width * height];
- assert(_vidMem);
- memset(_vidMem, 0, width * height);
+ dst += surf.getWidth() - _itemWidth;
+ }
}
-void SurfaceDesc::swap(SurfaceDesc &surf) {
- SWAP(_width, surf._width);
- SWAP(_height, surf._height);
- SWAP(_vidMode, surf._vidMode);
- SWAP(_ownVidMem, surf._ownVidMem);
- SWAP(_vidMem, surf._vidMem);
+const byte *Font::getCharData(uint8 c) const {
+ if (_endItem == 0) {
+ warning("Font::getCharData(): _endItem == 0");
+ return 0;
+ }
+
+ if ((c < _startItem) || (c > _endItem))
+ return 0;
+
+ return _data + (c - _startItem) * _itemSize;
}
+
Video::Video(GobEngine *vm) : _vm(vm) {
_doRangeClamp = false;
_videoDriver = 0;
@@ -222,8 +207,8 @@ void Video::initPrimary(int16 mode) {
}
}
-SurfaceDescPtr Video::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) {
- SurfaceDescPtr descPtr;
+SurfacePtr Video::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) {
+ SurfacePtr descPtr;
if (flags & PRIMARY_SURFACE)
assert((width == _surfWidth) && (height == _surfHeight));
@@ -236,14 +221,13 @@ SurfaceDescPtr Video::initSurfDesc(int16 vidMode, int16 width, int16 height, int
descPtr = _vm->_global->_primarySurfDesc;
descPtr->resize(width, height);
- descPtr->_vidMode = vidMode;
} else {
assert(!(flags & DISABLE_SPR_ALLOC));
if (!(flags & SCUMMVM_CURSOR))
width = (width + 7) & 0xFFF8;
- descPtr = SurfaceDescPtr(new SurfaceDesc(vidMode, width, height));
+ descPtr = SurfacePtr(new Surface(width, height, 1));
}
return descPtr;
}
@@ -280,8 +264,7 @@ void Video::retrace(bool mouse) {
screenWidth = MIN<int>(_vm->_width, _splitSurf->getWidth());
screenHeight = _splitSurf->getHeight();
- g_system->copyRectToScreen(_splitSurf->getVidMem() + screenOffset,
- _splitSurf->getWidth(), screenX, screenY, screenWidth, screenHeight);
+ _splitSurf->blitToScreen(0, 0, screenWidth - 1, screenHeight - 1, screenX, screenY);
} else if (_splitHeight2 > 0) {
@@ -317,191 +300,58 @@ void Video::sparseRetrace(int max) {
_lastSparse = timeKey;
}
-void Video::putPixel(int16 x, int16 y, int16 color, SurfaceDesc &dest) {
- if ((x >= dest.getWidth()) || (x < 0) ||
- (y >= dest.getHeight()) || (y < 0))
- return;
+void Video::drawPacked(byte *sprBuf, int16 width, int16 height,
+ int16 x, int16 y, byte transp, Surface &dest) {
- _videoDriver->putPixel(x, y, color, dest);
-}
-
-void Video::fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right,
- int16 bottom, int16 color) {
-
- if (_doRangeClamp) {
- if (left > right)
- SWAP(left, right);
- if (top > bottom)
- SWAP(top, bottom);
-
- if ((left >= dest.getWidth()) || (right < 0) ||
- (top >= dest.getHeight()) || (bottom < 0))
- return;
-
- left = CLIP(left, (int16)0, (int16)(dest.getWidth() - 1));
- top = CLIP(top, (int16)0, (int16)(dest.getHeight() - 1));
- right = CLIP(right, (int16)0, (int16)(dest.getWidth() - 1));
- bottom = CLIP(bottom, (int16)0, (int16)(dest.getHeight() - 1));
- }
-
- _videoDriver->fillRect(dest, left, top, right, bottom, color);
-}
-
-void Video::drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1,
- int16 y1, int16 color) {
-
- if ((x0 == x1) || (y0 == y1))
- Video::fillRect(dest, x0, y0, x1, y1, color);
- else
- _videoDriver->drawLine(dest, x0, y0, x1, y1, color);
-}
-
-/*
- * The original's version of the Bresenham Algorithm was a bit "unclean"
- * and produced strange edges at 45, 135, 225 and 315 degrees, so using the
- * version found in the Wikipedia article about the
- * "Bresenham's line algorithm" instead
- */
-void Video::drawCircle(SurfaceDesc &dest, int16 x0, int16 y0,
- int16 radius, int16 color) {
- int16 f = 1 - radius;
- int16 ddFx = 0;
- int16 ddFy = -2 * radius;
- int16 x = 0;
- int16 y = radius;
- int16 tmpPattern = (_vm->_draw->_pattern & 0xFF);
-
- if (tmpPattern == 0) {
- putPixel(x0, y0 + radius, color, dest);
- putPixel(x0, y0 - radius, color, dest);
- putPixel(x0 + radius, y0, color, dest);
- putPixel(x0 - radius, y0, color, dest);
- } else
- warning ("Video::drawCircle - pattern %d", _vm->_draw->_pattern);
-
- while (x < y) {
- if (f >= 0) {
- y--;
- ddFy += 2;
- f += ddFy;
- }
- x++;
- ddFx += 2;
- f += ddFx + 1;
-
- switch (tmpPattern) {
- case -1:
- fillRect(dest, x0 - y, y0 + x, x0 + y, y0 + x, color);
- fillRect(dest, x0 - x, y0 + y, x0 + x, y0 + y, color);
- fillRect(dest, x0 - y, y0 - x, x0 + y, y0 - x, color);
- fillRect(dest, x0 - x, y0 - y, x0 + x, y0 - y, color);
- break;
- case 0:
- putPixel(x0 + x, y0 + y, color, dest);
- putPixel(x0 - x, y0 + y, color, dest);
- putPixel(x0 + x, y0 - y, color, dest);
- putPixel(x0 - x, y0 - y, color, dest);
- putPixel(x0 + y, y0 + x, color, dest);
- putPixel(x0 - y, y0 + x, color, dest);
- putPixel(x0 + y, y0 - x, color, dest);
- putPixel(x0 - y, y0 - x, color, dest);
- break;
- default:
- fillRect(dest, x0 + y - tmpPattern, y0 + x - tmpPattern, x0 + y, y0 + x, color);
- fillRect(dest, x0 + x - tmpPattern, y0 + y - tmpPattern, x0 + x, y0 + y, color);
- fillRect(dest, x0 - y, y0 + x - tmpPattern, x0 - y + tmpPattern, y0 + x, color);
- fillRect(dest, x0 - x, y0 + y - tmpPattern, x0 - x + tmpPattern, y0 + y, color);
- fillRect(dest, x0 + y - tmpPattern, y0 - x, x0 + y, y0 - x + tmpPattern, color);
- fillRect(dest, x0 + x - tmpPattern, y0 - y, x0 + x, y0 - y + tmpPattern, color);
- fillRect(dest, x0 - y, y0 - x, x0 - y + tmpPattern, y0 - x + tmpPattern, color);
- fillRect(dest, x0 - x, y0 - y, x0 - x + tmpPattern, y0 - y + tmpPattern, color);
- break;
- }
- }
-}
-
-void Video::clearSurf(SurfaceDesc &dest) {
- Video::fillRect(dest, 0, 0, dest.getWidth() - 1, dest.getHeight() - 1, 0);
-}
+ int destRight = x + width;
+ int destBottom = y + height;
-void Video::drawSprite(SurfaceDesc &source, SurfaceDesc &dest,
- int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) {
- int16 destRight;
- int16 destBottom;
+ Pixel dst = dest.get(x, y);
- if (_doRangeClamp) {
- if (left > right)
- SWAP(left, right);
- if (top > bottom)
- SWAP(top, bottom);
+ int curx = x;
+ int cury = y;
- if ((left >= source.getWidth()) || (right < 0) ||
- (top >= source.getHeight()) || (bottom < 0))
- return;
+ while (1) {
+ uint8 val = *sprBuf++;
+ unsigned int repeat = val & 7;
+ val &= 0xF8;
- if (left < 0) {
- x -= left;
- left = 0;
+ if (!(val & 8)) {
+ repeat <<= 8;
+ repeat |= *sprBuf++;
}
- if (top < 0) {
- y -= top;
- top = 0;
+ repeat++;
+ val >>= 4;
+
+ for (unsigned int i = 0; i < repeat; ++i) {
+ if (curx < dest.getWidth() && cury < dest.getHeight())
+ if (!transp || val)
+ dst.set(val);
+
+ dst++;
+ curx++;
+ if (curx == destRight) {
+ dst += dest.getWidth() + x - curx;
+ curx = x;
+ cury++;
+ if (cury == destBottom)
+ return;
+ }
}
- right = CLIP(right, (int16)0, (int16)(source.getWidth() - 1));
- bottom = CLIP(bottom, (int16)0, (int16)(source.getHeight() - 1));
- if (right - left >= source.getWidth())
- right = left + source.getWidth() - 1;
- if (bottom - top >= source.getHeight())
- bottom = top + source.getHeight() - 1;
-
- if (x < 0) {
- left -= x;
- x = 0;
- }
- if (y < 0) {
- top -= y;
- y = 0;
- }
- if ((x >= dest.getWidth()) || (left > right) ||
- (y >= dest.getHeight()) || (top > bottom))
- return;
- destRight = x + right - left;
- destBottom = y + bottom - top;
- if (destRight >= dest.getWidth())
- right -= destRight - dest.getWidth() + 1;
-
- if (destBottom >= dest.getHeight())
- bottom -= destBottom - dest.getHeight() + 1;
}
-
- _videoDriver->drawSprite(source, dest, left, top, right, bottom, x, y, transp);
-}
-
-void Video::drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest,
- int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) {
-
- _videoDriver->drawSpriteDouble(source, dest, left, top, right, bottom, x, y, transp);
-}
-
-void Video::drawLetter(int16 item, int16 x, int16 y, const Font &font,
- int16 color1, int16 color2, int16 transp, SurfaceDesc &dest) {
- assert(item != 0x00);
- _videoDriver->drawLetter((unsigned char)item, x, y, font, color1, color2, transp, dest);
}
void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height,
- int16 x, int16 y, int16 transp, SurfaceDesc &dest) {
+ int16 x, int16 y, int16 transp, Surface &dest) {
if (spriteUncompressor(sprBuf, width, height, x, y, transp, dest))
return;
- _vm->validateVideoMode(dest._vidMode);
-
- _videoDriver->drawPackedSprite(sprBuf, width, height, x, y, transp, dest);
+ drawPacked(sprBuf, width, height, x, y, transp, dest);
}
-void Video::drawPackedSprite(const char *path, SurfaceDesc &dest, int width) {
+void Video::drawPackedSprite(const char *path, Surface &dest, int width) {
byte *data;
data = _vm->_dataIO->getData(path);
@@ -589,32 +439,25 @@ void Video::dirtyRectsAdd(int16 left, int16 top, int16 right, int16 bottom) {
}
void Video::dirtyRectsApply(int left, int top, int width, int height, int x, int y) {
- byte *vidMem = _vm->_global->_primarySurfDesc->getVidMem();
-
if (_dirtyAll) {
- g_system->copyRectToScreen(vidMem + top * _surfWidth + left,
- _surfWidth, x, y, width, height);
+ _vm->_global->_primarySurfDesc->blitToScreen(left, top, left + width - 1, top + height - 1, x, y);
return;
}
- int right = left + width;
- int bottom = top + height;
+ int right = left + width;
+ int bottom = top + height;
Common::List<Common::Rect>::const_iterator it;
for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
- int l = MAX<int>(left, it->left);
- int t = MAX<int>(top, it->top);
- int r = MIN<int>(right, it->right);
+ int l = MAX<int>(left , it->left);
+ int t = MAX<int>(top , it->top);
+ int r = MIN<int>(right , it->right);
int b = MIN<int>(bottom, it->bottom);
- int w = r - l;
- int h = b - t;
- if ((w <= 0) || (h <= 0))
+ if ((r <= l) || (b <= t))
continue;
- byte *v = vidMem + t * _surfWidth + l;
-
- g_system->copyRectToScreen(v, _surfWidth, x + (l - left), y + (t - top), w, h);
+ _vm->_global->_primarySurfDesc->blitToScreen(l, t, r - 1, b - 1, x + (l - left), y + (t - top));
}
}