diff options
author | Benjamin Haisch | 2008-09-17 17:08:33 +0000 |
---|---|---|
committer | Willem Jan Palenstijn | 2011-11-20 22:43:06 +0100 |
commit | d299bbba01d3955d41d2ca3ebddca98a31f7eb27 (patch) | |
tree | e765eeab015d1a5508b0e34fee431df461537179 /engines/toltecs/segmap.cpp | |
parent | 150e555953d8efae73d1275e138586c91f655809 (diff) | |
download | scummvm-rg350-d299bbba01d3955d41d2ca3ebddca98a31f7eb27.tar.gz scummvm-rg350-d299bbba01d3955d41d2ca3ebddca98a31f7eb27.tar.bz2 scummvm-rg350-d299bbba01d3955d41d2ca3ebddca98a31f7eb27.zip |
TOLTECS: Changed how screen masks are handled.
At load time, a Surface is created for each screen mask, in which the gfx data from the background is copied.
This is the first step towards more optimized gfx rendering (more to come later).
Diffstat (limited to 'engines/toltecs/segmap.cpp')
-rw-r--r-- | engines/toltecs/segmap.cpp | 119 |
1 files changed, 56 insertions, 63 deletions
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp index 28965ceb4f..6a3f849d4a 100644 --- a/engines/toltecs/segmap.cpp +++ b/engines/toltecs/segmap.cpp @@ -43,22 +43,23 @@ namespace Toltecs { SegmentMap::SegmentMap(ToltecsEngine *vm) : _vm(vm) { - _maskRectData = new byte[32768]; } SegmentMap::~SegmentMap() { - delete[] _maskRectData; + freeSegmapMaskRectSurfaces(); } void SegmentMap::load(byte *source) { // TODO: Use MemoryReadStream + freeSegmapMaskRectSurfaces(); _maskRects.clear(); _pathRects.clear(); _infoRects.clear(); // Load mask rects + byte *maskData = source + 2; uint16 maskSize = READ_LE_UINT16(source); source += 2; uint16 maskRectCount = READ_LE_UINT16(source); @@ -69,24 +70,24 @@ void SegmentMap::load(byte *source) { for (uint16 i = 0; i < maskRectCount; i++) { SegmapMaskRect maskRect; + int16 maskOffset; maskRect.y = READ_LE_UINT16(source); maskRect.x = READ_LE_UINT16(source + 2); maskRect.height = READ_LE_UINT16(source + 4); maskRect.width = READ_LE_UINT16(source + 6); - maskRect.maskOffset = READ_LE_UINT16(source + 8); - maskRect.maskOffset -= maskRectDataSize; + maskOffset = READ_LE_UINT16(source + 8); maskRect.priority = READ_LE_UINT16(source + 10); + loadSegmapMaskRectSurface(maskData + maskOffset, maskRect); debug(0, "SegmentMap::load() (%d, %d, %d, %d, %04X, %d)", - maskRect.x, maskRect.y, maskRect.width, maskRect.height, maskRect.maskOffset, maskRect.priority); + maskRect.x, maskRect.y, maskRect.width, maskRect.height, maskOffset, maskRect.priority); source += 12; _maskRects.push_back(maskRect); } - memcpy(_maskRectData, source, maskSize - maskRectDataSize); source += maskSize - maskRectDataSize; - + // Load path rects source += 2; // skip rects array size @@ -304,7 +305,7 @@ void SegmentMap::findPath(int16 *pointsArray, int16 destX, int16 destY, int16 so pointsCount = 2; - adjustPathPoint(sourceX, sourceY); + adjustPathPoint(sourceX, sourceY); currentRectIndex = findPathRectAtPoint(sourceX, sourceY); adjustPathPoint(destX, destY); @@ -388,44 +389,59 @@ void SegmentMap::getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byt debug(0, "SegmentMap::getRgbModifiertAtPoint() r: %d; g: %d; b: %d", r, g, b); } +void SegmentMap::loadSegmapMaskRectSurface(byte *maskData, SegmapMaskRect &maskRect) { + + maskRect.surface = new Graphics::Surface(); + maskRect.surface->create(maskRect.width, maskRect.height, 1); + + byte *backScreen = _vm->_screen->_backScreen + maskRect.x + (maskRect.y * _vm->_sceneWidth); + byte *dest = (byte*)maskRect.surface->getBasePtr(0, 0); + + for (int16 h = 0; h < maskRect.height; h++) { + int16 w = maskRect.width; + while (w > 0) { + byte mask = *maskData++; + byte count = mask & 0x7F; + if (mask & 0x80) + memcpy(dest, backScreen, count); + else + memset(dest, 0xFF, count); + w -= count; + dest += count; + backScreen += count; + } + backScreen += _vm->_sceneWidth - maskRect.width; + } + +} + +void SegmentMap::freeSegmapMaskRectSurfaces() { + for (uint i = 0; i < _maskRects.size(); i++) { + delete _maskRects[i].surface; + } +} + void SegmentMap::restoreMasksBySprite(SpriteDrawItem *sprite) { // TODO: This needs more optimization for (uint i = 0; i < _maskRects.size(); i++) { - -#if 0 - if ( *(__int16 *)((char *)&spriteDrawList[0].y2 + v5) <= (unsigned __int16)v3->priority ) - { - if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].height + v5) - + *(__int16 *)((char *)&spriteDrawList[0].y + v5)) > v3->y ) - { - if ( (unsigned __int16)(v3->height + v3->y) > *(__int16 *)((char *)&spriteDrawList[0].y + v5) ) - { - if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].width + v5) - + *(__int16 *)((char *)&spriteDrawList[0].x + v5)) > v3->x ) - { - if ( (unsigned __int16)(v3->width + v3->x) > *(__int16 *)((char *)&spriteDrawList[0].x + v5) ) - { - -#endif - if (sprite->priority <= _maskRects[i].priority) { restoreMask(i); } } - } void SegmentMap::restoreMask(int16 index) { + // TODO: This needs more optimization SegmapMaskRect *maskRect = &_maskRects[index]; - int16 maskX = maskRect->x, maskY = maskRect->y; int16 skipX = 0; int16 x = maskRect->x - _vm->_cameraX; int16 y = maskRect->y - _vm->_cameraY; int16 width = maskRect->width; int16 height = maskRect->height; - byte *mask = _maskRectData + maskRect->maskOffset; + byte *maskSurface = (byte*)maskRect->surface->getBasePtr(0, 0); + byte *frontScreen; debug(0, "SegmentMap::restoreMask() screenX = %d; screenY = %d; maskX = %d; maskY = %d", x, y, maskRect->x, maskRect->y); @@ -437,19 +453,14 @@ void SegmentMap::restoreMask(int16 index) { if (x < 0) { skipX = -x; x = 0; + width -= skipX; } if (y < 0) { int16 skipY = -y; - for (int16 h = 0; h < skipY; h++) { - int16 w = width; - while (w > 0) { - w -= (*mask++) & 0x7F; - } - } + maskSurface += maskRect->width * skipY; y = 0; height -= skipY; - maskY += skipY; } if (x + width >= 640) { @@ -460,38 +471,20 @@ void SegmentMap::restoreMask(int16 index) { height -= y + height - _vm->_cameraHeight; } - byte *backScreen = _vm->_screen->_backScreen + maskX + (maskY * _vm->_sceneWidth); - byte *frontScreen = _vm->_screen->_frontScreen + x + (y * 640); + frontScreen = _vm->_screen->_frontScreen + x + (y * 640); for (int16 h = 0; h < height; h++) { - byte *src = backScreen; - byte *dst = frontScreen; - byte maskLine[640], *maskLineP = maskLine; - - int16 w = width; - while (w > 0) { - byte m = *mask++; - byte count = m & 0x7F; - if (m & 0x80) - memset(maskLineP, 1, count); - else - memset(maskLineP, 0, count); - maskLineP += count; - w -= count; - } - - src += skipX; - for (int16 c = skipX; c < width; c++) { - if (maskLine[c] == 1) - *dst = *src; - dst++; - src++; + maskSurface += skipX; + for (int16 w = 0; w < width; w++) { + if (*maskSurface != 0xFF) + *frontScreen = *maskSurface; + frontScreen++; + maskSurface++; } - - backScreen += _vm->_sceneWidth; - frontScreen += 640; + frontScreen += 640 - width; + maskSurface += maskRect->width - width - skipX; } - + } void SegmentMap::debugDrawRects(Graphics::Surface *surf) { |