diff options
-rw-r--r-- | engines/toltecs/segmap.cpp | 119 | ||||
-rw-r--r-- | engines/toltecs/segmap.h | 13 |
2 files changed, 62 insertions, 70 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) { diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h index 7e5150ba4a..6c20eac431 100644 --- a/engines/toltecs/segmap.h +++ b/engines/toltecs/segmap.h @@ -80,17 +80,13 @@ public: public: // for debugging purposes struct SegmapMaskRect { - int16 y, x; - int16 height, width; - int16 maskOffset; + int16 x, y; + int16 width, height; int16 priority; + Graphics::Surface *surface; }; struct SegmapPathRect { - /* - int16 y, x; - int16 height, width; - */ int16 x1, y1, x2, y2; }; @@ -128,6 +124,9 @@ public: // for debugging purposes int16 findNextPathRect(int16 srcRectIndex, int16 destX, int16 destY); + void loadSegmapMaskRectSurface(byte *maskData, SegmapMaskRect &maskRect); + void freeSegmapMaskRectSurfaces(); + }; } // End of namespace Toltecs |