aboutsummaryrefslogtreecommitdiff
path: root/engines/toltecs
diff options
context:
space:
mode:
Diffstat (limited to 'engines/toltecs')
-rw-r--r--engines/toltecs/segmap.cpp119
-rw-r--r--engines/toltecs/segmap.h13
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