aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/draw_fascin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/draw_fascin.cpp')
-rw-r--r--engines/gob/draw_fascin.cpp848
1 files changed, 805 insertions, 43 deletions
diff --git a/engines/gob/draw_fascin.cpp b/engines/gob/draw_fascin.cpp
index 1e01db7dfb..86e5cb8314 100644
--- a/engines/gob/draw_fascin.cpp
+++ b/engines/gob/draw_fascin.cpp
@@ -28,6 +28,8 @@
#include "gob/draw.h"
#include "gob/game.h"
+#include "gob/global.h"
+#include "gob/inter.h"
#include "gob/resources.h"
namespace Gob {
@@ -38,7 +40,7 @@ Draw_Fascination::Draw_Fascination(GobEngine *vm) : Draw_v2(vm) {
void Draw_Fascination::spriteOperation(int16 operation) {
int16 len;
int16 x, y;
- SurfaceDescPtr sourceSurf, destSurf;
+ SurfacePtr sourceSurf, destSurf;
bool deltaVeto;
int16 left;
int16 ratio;
@@ -71,7 +73,7 @@ void Draw_Fascination::spriteOperation(int16 operation) {
if (_renderFlags & 0x20) {
if (_destSurface == kBackSurface || (operation == 0 && _sourceSurface == kBackSurface)) {
- winDraw(operation);
+ drawWin(operation);
return;
}
}
@@ -147,26 +149,24 @@ void Draw_Fascination::spriteOperation(int16 operation) {
if (!sourceSurf || !destSurf)
break;
- _vm->_video->drawSprite(*_spritesArray[_sourceSurface],
- *_spritesArray[_destSurface],
+ _spritesArray[_destSurface]->blit(*_spritesArray[_sourceSurface],
_spriteLeft, spriteTop,
_spriteLeft + _spriteRight - 1,
_spriteTop + _spriteBottom - 1,
- _destSpriteX, _destSpriteY, _transparency);
+ _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0);
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
break;
case DRAW_PUTPIXEL:
- _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor,
- *_spritesArray[_destSurface]);
+ _spritesArray[_destSurface]->putPixel(_destSpriteX, _destSpriteY, _frontColor);
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY);
break;
case DRAW_FILLRECT:
- _vm->_video->fillRect(*_spritesArray[_destSurface], destSpriteX,
+ _spritesArray[_destSurface]->fillRect(destSpriteX,
_destSpriteY, _destSpriteX + _spriteRight - 1,
_destSpriteY + _spriteBottom - 1, _backColor);
@@ -175,15 +175,14 @@ void Draw_Fascination::spriteOperation(int16 operation) {
break;
case DRAW_DRAWLINE:
- _vm->_video->drawLine(*_spritesArray[_destSurface],
- _destSpriteX, _destSpriteY,
+ _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY,
_spriteRight, _spriteBottom, _frontColor);
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom);
break;
case DRAW_INVALIDATE:
- _vm->_video->drawCircle(*_spritesArray[_destSurface], _destSpriteX,
+ _spritesArray[_destSurface]->drawCircle(_destSpriteX,
_destSpriteY, _spriteRight, _frontColor);
dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom,
@@ -225,9 +224,8 @@ void Draw_Fascination::spriteOperation(int16 operation) {
byte *dataBuf = _vm->_game->_resources->getTexts() + _textToPrint[1] + 1;
len = *dataBuf++;
for (int i = 0; i < len; i++, dataBuf += 2) {
- _vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX,
- _destSpriteY, *font, _transparency, _frontColor,
- _backColor, *_spritesArray[_destSurface]);
+ font->drawLetter(*_spritesArray[_destSurface], READ_LE_UINT16(dataBuf),
+ _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency);
}
} else {
drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor,
@@ -236,9 +234,8 @@ void Draw_Fascination::spriteOperation(int16 operation) {
}
} else {
for (int i = 0; i < len; i++) {
- _vm->_video->drawLetter(_textToPrint[i], _destSpriteX,
- _destSpriteY, *font, _transparency,
- _frontColor, _backColor, *_spritesArray[_destSurface]);
+ font->drawLetter(*_spritesArray[_destSurface], _textToPrint[i],
+ _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency);
_destSpriteX += font->getCharWidth(_textToPrint[i]);
}
}
@@ -253,11 +250,10 @@ void Draw_Fascination::spriteOperation(int16 operation) {
* _fontToSprite[_fontIndex].height;
x = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) % ratio)
* _fontToSprite[_fontIndex].width;
- _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite],
- *_spritesArray[_destSurface], x, y,
+ _spritesArray[_destSurface]->blit(*_spritesArray[_fontToSprite[_fontIndex].sprite], x, y,
x + _fontToSprite[_fontIndex].width - 1,
y + _fontToSprite[_fontIndex].height - 1,
- _destSpriteX, _destSpriteY, _transparency);
+ _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0);
_destSpriteX += _fontToSprite[_fontIndex].width;
}
}
@@ -268,36 +264,28 @@ void Draw_Fascination::spriteOperation(int16 operation) {
case DRAW_DRAWBAR:
if (_needAdjust != 2) {
- _vm->_video->fillRect(*_spritesArray[_destSurface],
- _destSpriteX, _spriteBottom - 1,
+ _spritesArray[_destSurface]->fillRect(_destSpriteX, _spriteBottom - 1,
_spriteRight, _spriteBottom, _frontColor);
- _vm->_video->fillRect(*_spritesArray[_destSurface],
- _destSpriteX, _destSpriteY,
+ _spritesArray[_destSurface]->fillRect( _destSpriteX, _destSpriteY,
_destSpriteX + 1, _spriteBottom, _frontColor);
- _vm->_video->fillRect(*_spritesArray[_destSurface],
- _spriteRight - 1, _destSpriteY,
+ _spritesArray[_destSurface]->fillRect( _spriteRight - 1, _destSpriteY,
_spriteRight, _spriteBottom, _frontColor);
- _vm->_video->fillRect(*_spritesArray[_destSurface],
- _destSpriteX, _destSpriteY,
+ _spritesArray[_destSurface]->fillRect( _destSpriteX, _destSpriteY,
_spriteRight, _destSpriteY + 1, _frontColor);
} else {
- _vm->_video->drawLine(*_spritesArray[_destSurface],
- _destSpriteX, _spriteBottom,
+ _spritesArray[_destSurface]->drawLine(_destSpriteX, _spriteBottom,
_spriteRight, _spriteBottom, _frontColor);
- _vm->_video->drawLine(*_spritesArray[_destSurface],
- _destSpriteX, _destSpriteY,
+ _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY,
_destSpriteX, _spriteBottom, _frontColor);
- _vm->_video->drawLine(*_spritesArray[_destSurface],
- _spriteRight, _destSpriteY,
+ _spritesArray[_destSurface]->drawLine(_spriteRight, _destSpriteY,
_spriteRight, _spriteBottom, _frontColor);
- _vm->_video->drawLine(*_spritesArray[_destSurface],
- _destSpriteX, _destSpriteY,
+ _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY,
_spriteRight, _destSpriteY, _frontColor);
}
@@ -306,19 +294,14 @@ void Draw_Fascination::spriteOperation(int16 operation) {
case DRAW_CLEARRECT:
if ((_backColor != 16) && (_backColor != 144)) {
- _vm->_video->fillRect(*_spritesArray[_destSurface],
- _destSpriteX, _destSpriteY,
- _spriteRight, _spriteBottom,
- _backColor);
+ _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor);
}
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom);
break;
case DRAW_FILLRECTABS:
- _vm->_video->fillRect(*_spritesArray[_destSurface],
- _destSpriteX, _destSpriteY,
- _spriteRight, _spriteBottom, _backColor);
+ _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor);
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom);
break;
@@ -352,4 +335,783 @@ void Draw_Fascination::spriteOperation(int16 operation) {
}
}
+void Draw_Fascination::drawWin(int16 fct) {
+ int16 left;
+ int16 top;
+ int16 width;
+ int16 height;
+
+ bool found = false;
+ int len;
+ Resource *resource;
+ int table[10];
+ SurfacePtr tempSrf;
+
+ if (_destSurface == kBackSurface) {
+
+ if (_vm->_global->_curWinId) {
+ if (_fascinWin[_vm->_global->_curWinId].id == -1)
+ return;
+
+ else {
+ _destSpriteX += _fascinWin[_vm->_global->_curWinId].left;
+ _destSpriteY += _fascinWin[_vm->_global->_curWinId].top;
+ if (fct == 3 || (fct >= 7 && fct <= 9)) {
+ _spriteRight += _fascinWin[_vm->_global->_curWinId].left;
+ _spriteBottom += _fascinWin[_vm->_global->_curWinId].top;
+ }
+ }
+ }
+
+ left = _destSpriteX;
+ top = _destSpriteY;
+
+ } else {
+ if (_vm->_global->_curWinId) {
+ if (_fascinWin[_vm->_global->_curWinId].id == -1)
+ return;
+ else {
+ _spriteLeft += _fascinWin[_vm->_global->_curWinId].left;
+ _spriteTop += _fascinWin[_vm->_global->_curWinId].top;
+ }
+ }
+
+ left = _spriteLeft;
+ top = _spriteTop;
+ }
+
+ for (int i = 0; i < 10; i++)
+ table[i] = 0;
+
+ switch (fct) {
+ case DRAW_BLITSURF: // 0 - move
+ case DRAW_FILLRECT: // 2 - fill rectangle
+ width = left + _spriteRight - 1;
+ height = top + _spriteBottom - 1;
+ break;
+
+ case DRAW_PUTPIXEL: // 1 - put a pixel
+ width = _destSpriteX;
+ height = _destSpriteY;
+ break;
+
+ case DRAW_DRAWLINE: // 3 - draw line
+ case DRAW_DRAWBAR: // 7 - draw border
+ case DRAW_CLEARRECT: // 8 - clear rectangle
+ case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates
+ width = _spriteRight;
+ height = _spriteBottom;
+ break;
+
+ case DRAW_INVALIDATE: // 4 - Draw a circle
+ left = _destSpriteX - _spriteRight;
+ top = _destSpriteY - _spriteRight;
+ width = _destSpriteX + _spriteRight;
+ height = _destSpriteY + _spriteBottom;
+ break;
+
+ case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite
+ // TODO: check the implementation, currently dirty cut and paste of DRAW_SPRITE code
+ resource = _vm->_game->_resources->getResource((_spriteLeft & 0x3FFF),
+ &_spriteRight, &_spriteBottom);
+
+ if (!resource) {
+ width = 0;
+ height = 0;
+ break;
+ }
+
+ _vm->_video->drawPackedSprite(resource->getData(),
+ _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
+ _transparency, *_spritesArray[_destSurface]);
+
+ dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
+ _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
+
+ delete resource;
+
+ width = _destSpriteX + _spriteRight - 1;
+ height = _destSpriteY + _spriteBottom - 1;
+ break;
+
+ case DRAW_PRINTTEXT: // 6 - Display string
+ width = _destSpriteX - 1 + strlen(_textToPrint) * _fonts[_fontIndex]->getCharWidth();
+ height = _destSpriteY - 1 + _fonts[_fontIndex]->getCharHeight();
+ break;
+
+ case DRAW_DRAWLETTER: // 10 - Display a character
+ if (_fontToSprite[_fontIndex].sprite == -1) {
+ width = _destSpriteX - 1 + _fonts[_fontIndex]->getCharWidth();
+ height = _destSpriteY - 1 + _fonts[_fontIndex]->getCharHeight();
+ } else {
+ width = _destSpriteX + _fontToSprite[_fontIndex].width - 1;
+ height = _destSpriteY + _fontToSprite[_fontIndex].height - 1;
+ }
+ break;
+
+ default:
+ error("winDraw - Unexpected fct value %d", fct);
+ break;
+ }
+
+ for (int i = 0; i < 10; i++) {
+ if ((i != _vm->_global->_curWinId) && (_fascinWin[i].id != -1)) {
+ if (!_vm->_global->_curWinId || _fascinWin[i].id>_fascinWin[_vm->_global->_curWinId].id) {
+ if ((_fascinWin[i].left + _fascinWin[i].width > left) && (width >= _fascinWin[i].left) &&
+ (_fascinWin[i].top + _fascinWin[i].height > top ) && (height >= _fascinWin[i].top)) {
+ found = true;
+ table[_fascinWin[i].id] = i;
+ }
+ }
+ }
+ }
+
+ if ((_sourceSurface == kBackSurface) && (fct == 0)) {
+ _spritesArray[_destSurface]->blit(*_spritesArray[_sourceSurface],
+ _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1,
+ _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0);
+ if (!found)
+ return;
+
+ int j = 0;
+ if (_vm->_global->_curWinId != 0)
+ j = _fascinWin[_vm->_global->_curWinId].id + 1;
+
+ for (int i = 9; i >= j; i--) {
+ if (table[i])
+ _spritesArray[_destSurface]->blit(*_fascinWin[table[i]].savedSurface,
+ _fascinWin[table[i]].left & 7, 0,
+ (_fascinWin[table[i]].left & 7) + _fascinWin[table[i]].width - 1,
+ _fascinWin[table[i]].height - 1, _fascinWin[table[i]].left - _spriteLeft + _destSpriteX,
+ _fascinWin[table[i]].top - _spriteTop + _destSpriteY);
+ }
+ return;
+ }
+
+ if (found) {
+ tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width - left + 1, height - top + 1, 0);
+ tempSrf->blit(*_backSurface, left, top, width, height, 0, 0);
+
+ int max = 0;
+ if (_vm->_global->_curWinId != 0)
+ max = _fascinWin[_vm->_global->_curWinId].id + 1;
+
+ for (int i = 9; i >= max; i--) {
+ if (table[i])
+ tempSrf->blit(*_fascinWin[table[i]].savedSurface,
+ _fascinWin[table[i]].left & 7, 0,
+ (_fascinWin[table[i]].left & 7) + _fascinWin[table[i]].width - 1,
+ _fascinWin[table[i]].height - 1,
+ _fascinWin[table[i]].left - left,
+ _fascinWin[table[i]].top - top);
+ }
+
+ invalidateRect(left, top, width, height);
+
+ switch (fct) {
+ case DRAW_BLITSURF: // 0 - move
+ tempSrf->blit(*_spritesArray[_sourceSurface],
+ _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1,
+ _spriteTop + _spriteBottom - 1, 0, 0, (_transparency == 0) ? -1 : 0);
+ break;
+
+ case DRAW_PUTPIXEL: // 1 - put a pixel
+ tempSrf->putPixel(0, 0, _frontColor);
+ break;
+
+ case DRAW_FILLRECT: // 2 - fill rectangle
+ tempSrf->fillRect(0, 0, _spriteRight - 1, _spriteBottom - 1, _backColor);
+ break;
+
+ case DRAW_DRAWLINE: // 3 - draw line
+ tempSrf->drawLine(0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor);
+ break;
+
+ case DRAW_INVALIDATE: // 4 - Draw a circle
+ tempSrf->drawCircle(_spriteRight, _spriteRight, _spriteRight, _frontColor);
+ break;
+
+ case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite
+ decompWin(0, 0, tempSrf);
+ break;
+
+ case DRAW_PRINTTEXT: // 6 - Display string
+ len = strlen(_textToPrint);
+ for (int j = 0; j < len; j++)
+ _fonts[_fontIndex]->drawLetter(*tempSrf, _textToPrint[j],
+ j * _fonts[_fontIndex]->getCharWidth(), 0, _frontColor, _backColor, _transparency);
+ _destSpriteX += len * _fonts[_fontIndex]->getCharWidth();
+ break;
+
+ case DRAW_DRAWBAR: // 7 - draw border
+ tempSrf->drawLine(0, _spriteBottom - _destSpriteY, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor);
+ tempSrf->drawLine(0, 0, 0, _spriteBottom - _destSpriteY, _frontColor);
+ tempSrf->drawLine(_spriteRight - _destSpriteX, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor);
+ tempSrf->drawLine(0, 0, _spriteRight - _destSpriteX, 0, _frontColor);
+ break;
+
+ case DRAW_CLEARRECT: // 8 - clear rectangle
+ if (_backColor < 16)
+ tempSrf->fillRect(0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor);
+ break;
+
+ case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates
+ tempSrf->fillRect(0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor);
+ break;
+
+ case DRAW_DRAWLETTER: // 10 - Display a character
+ if (_fontToSprite[_fontIndex].sprite == -1) {
+
+ if (_letterToPrint)
+ _fonts[_fontIndex]->drawLetter(*tempSrf, _letterToPrint, 0, 0, _frontColor, _backColor, _transparency);
+ } else {
+ int xx, yy, nn;
+ nn = _spritesArray[_fontToSprite[_fontIndex].sprite]->getWidth() / _fontToSprite[_fontIndex].width;
+ yy = ((_letterToPrint - _fontToSprite[_fontIndex].base) / nn) * _fontToSprite[_fontIndex].height;
+ xx = ((_letterToPrint - _fontToSprite[_fontIndex].base) % nn) * _fontToSprite[_fontIndex].width;
+ tempSrf->blit(*_spritesArray[_fontToSprite[_fontIndex].sprite],
+ xx, yy, xx + _fontToSprite[_fontIndex].width - 1,
+ yy + _fontToSprite[_fontIndex].height - 1, 0, 0, (_transparency == 0) ? -1 : 0);
+ }
+ break;
+
+ default:
+ error("winDraw - Unexpected fct value %d", fct);
+ break;
+ }
+
+ int i = 0;
+ if (_vm->_global->_curWinId != 0)
+ i = _fascinWin[_vm->_global->_curWinId].id + 1;
+
+ for (; i < 10; i++) {
+ if (table[i]) {
+ int k = table[i];
+ _fascinWin[k].savedSurface->blit(*tempSrf,
+ 0, 0, width - left, height - top,
+ left - _fascinWin[k].left + (_fascinWin[k].left & 7),
+ top - _fascinWin[k].top);
+ // Shift skipped as always set to zero (?)
+ tempSrf->blit(*_frontSurface,
+ MAX(left , _fascinWin[k].left),
+ MAX(top , _fascinWin[k].top),
+ MIN(width , (int16) (_fascinWin[k].left + _fascinWin[k].width - 1)),
+ MIN(height, (int16) (_fascinWin[k].top + _fascinWin[k].height - 1)),
+ MAX(left , _fascinWin[k].left) - left,
+ MAX(top , _fascinWin[k].top) - top);
+ if (_cursorIndex != -1)
+ tempSrf->blit(*_cursorSpritesBack,
+ 0, 0, _cursorWidth - 1, _cursorHeight - 1,
+ _cursorX - left, _cursorY - top);
+ for (int j = 9; j > i; j--) {
+ if (table[j] && overlapWin(k, table[j])) {
+ int l = table[j];
+ tempSrf->blit(*_fascinWin[l].savedSurface,
+ MAX(_fascinWin[l].left, _fascinWin[k].left)
+ - _fascinWin[l].left + (_fascinWin[l].left & 7),
+ MAX(_fascinWin[l].top , _fascinWin[k].top ) - _fascinWin[l].top,
+ MIN(_fascinWin[l].left + _fascinWin[l].width - 1, _fascinWin[k].left + _fascinWin[k].width - 1)
+ - _fascinWin[l].left + (_fascinWin[l].left & 7),
+ MIN(_fascinWin[l].top + _fascinWin[l].height - 1, _fascinWin[k].top + _fascinWin[k].height - 1)
+ - _fascinWin[l].top,
+ MAX(_fascinWin[l].left, _fascinWin[k].left) - left,
+ MAX(_fascinWin[l].top , _fascinWin[k].top ) - top);
+ }
+ }
+ }
+ }
+ _backSurface->blit(*tempSrf, 0, 0, width - left, height - top, left, top);
+ tempSrf.reset();
+ } else {
+ invalidateRect(left, top, width, height);
+ switch (fct) {
+ case DRAW_BLITSURF: // 0 - move
+ _backSurface->blit(*_spritesArray[_sourceSurface],
+ _spriteLeft, _spriteTop,
+ _spriteLeft + _spriteRight - 1,
+ _spriteTop + _spriteBottom - 1,
+ _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0);
+ break;
+ case DRAW_PUTPIXEL: // 1 - put a pixel
+ _backSurface->putPixel(_destSpriteX, _destSpriteY, _frontColor);
+ break;
+
+ case DRAW_FILLRECT: // 2 - fill rectangle
+ _backSurface->fillRect(_destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor);
+ break;
+
+ case DRAW_DRAWLINE: // 3 - draw line
+ _backSurface->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor);
+ break;
+
+ case DRAW_INVALIDATE: // 4 - Draw a circle
+ _backSurface->drawCircle(_spriteRight, _spriteRight, _spriteRight, _frontColor);
+ break;
+
+ case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite
+ decompWin(_destSpriteX, _destSpriteY, _backSurface);
+ break;
+
+ case DRAW_PRINTTEXT: // 6 - Display string
+ len = strlen(_textToPrint);
+ for (int j = 0; j < len; j++)
+ _fonts[_fontIndex]->drawLetter(*_backSurface, _textToPrint[j],
+ _destSpriteX + j * _fonts[_fontIndex]->getCharWidth(), _destSpriteY,
+ _frontColor, _backColor, _transparency);
+ _destSpriteX += len * _fonts[_fontIndex]->getCharWidth();
+ break;
+
+ case DRAW_DRAWBAR: // 7 - draw border
+ _backSurface->drawLine(_destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor);
+ _backSurface->drawLine(_destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor);
+ _backSurface->drawLine(_spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor);
+ _backSurface->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor);
+ break;
+
+ case DRAW_CLEARRECT: // 8 - clear rectangle
+ if (_backColor < 16)
+ _backSurface->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor);
+ break;
+
+ case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates
+ _backSurface->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor);
+ break;
+
+ case DRAW_DRAWLETTER: // 10 - Display a character
+ if (_fontToSprite[_fontIndex].sprite == -1) {
+ if (_letterToPrint)
+ _fonts[_fontIndex]->drawLetter(*_spritesArray[_destSurface], _letterToPrint,
+ _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency);
+ } else {
+ int xx, yy, nn;
+ nn = _spritesArray[_fontToSprite[_fontIndex].sprite]->getWidth() / _fontToSprite[_fontIndex].width;
+ yy = ((_letterToPrint - _fontToSprite[_fontIndex].base) / nn) * _fontToSprite[_fontIndex].height;
+ xx = ((_letterToPrint - _fontToSprite[_fontIndex].base) % nn) * _fontToSprite[_fontIndex].width;
+ _spritesArray[_destSurface]->blit(*_spritesArray[_fontToSprite[_fontIndex].sprite],
+ xx, yy,
+ xx + _fontToSprite[_fontIndex].width - 1,
+ yy + _fontToSprite[_fontIndex].height - 1,
+ _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0);
+ }
+ break;
+
+ default:
+ error("winDraw - Unexpected fct value");
+ break;
+ }
+ }
+
+ if (_renderFlags & 16) {
+ if (_sourceSurface == kBackSurface) {
+ _spriteLeft -= _backDeltaX;
+ _spriteTop -= _backDeltaY;
+ }
+ if (_destSurface == kBackSurface) {
+ _destSpriteX -= _backDeltaX;
+ _destSpriteY -= _backDeltaY;
+ }
+ }
+
+ if (_vm->_global->_curWinId) {
+ _destSpriteX -= _fascinWin[_vm->_global->_curWinId].left;
+ _destSpriteY -= _fascinWin[_vm->_global->_curWinId].top;
+ }
+}
+
+void Draw_Fascination::decompWin(int16 x, int16 y, SurfacePtr destPtr) {
+ Resource *resource;
+ resource = _vm->_game->_resources->getResource((uint16) _spriteLeft,
+ &_spriteRight, &_spriteBottom);
+
+ if (!resource)
+ return;
+
+ _vm->_video->drawPackedSprite(resource->getData(),
+ _spriteRight, _spriteBottom, x, y, _transparency, *destPtr);
+
+ delete resource;
+ return;
+}
+
+int16 Draw_Fascination::openWin(int16 id) {
+ if (_fascinWin[id].id != -1)
+ return 0;
+
+ _fascinWin[id].id = _winCount++;
+ _fascinWin[id].left = VAR((_winVarArrayLeft / 4) + id);
+ _fascinWin[id].top = VAR((_winVarArrayTop / 4) + id);
+ _fascinWin[id].width = VAR((_winVarArrayWidth / 4) + id);
+ _fascinWin[id].height = VAR((_winVarArrayHeight / 4) + id);
+
+ _fascinWin[id].savedSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 7, _winMaxHeight, 0);
+
+ saveWin(id);
+ WRITE_VAR((_winVarArrayStatus / 4) + id, VAR((_winVarArrayStatus / 4) + id) & 0xFFFFFFFE);
+
+ return 1;
+}
+
+int16 Draw_Fascination::getWinFromCoord(int16 &dx, int16 &dy) {
+ int16 bestMatch = -1;
+
+ if ((_renderFlags & 128) == 0)
+ return -1;
+
+ for (int i = 0; i < 10; i++) {
+ if (_fascinWin[i].id != -1) {
+ if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left) &&
+ (_vm->_global->_inter_mouseX < _fascinWin[i].left + _fascinWin[i].width) &&
+ (_vm->_global->_inter_mouseY >= _fascinWin[i].top) &&
+ (_vm->_global->_inter_mouseY < _fascinWin[i].top + _fascinWin[i].height)) {
+
+ if (_fascinWin[i].id == _winCount - 1) {
+ dx = _fascinWin[i].left;
+ dy = _fascinWin[i].top;
+ return(i);
+ } else {
+ if (_fascinWin[i].id > bestMatch)
+ bestMatch = _fascinWin[i].id;
+ }
+ }
+ }
+ }
+
+ if (bestMatch != -1)
+ return(0);
+ else
+ return(-1);
+}
+
+void Draw_Fascination::closeWin(int16 id) {
+ if (_fascinWin[id].id == -1)
+ return;
+
+ WRITE_VAR((_winVarArrayStatus / 4) + id, VAR((_winVarArrayStatus / 4) + id) | 1);
+ restoreWin(id);
+ _fascinWin[id].id = -1;
+ _fascinWin[id].savedSurface.reset();
+ _winCount--;
+}
+
+int16 Draw_Fascination::handleCurWin() {
+ int8 matchNum = 0;
+ int16 bestMatch = -1;
+
+ if ((_vm->_game->_mouseButtons != 1) || ((_renderFlags & 128) == 0))
+ return 0;
+
+ for (int i = 0; i < 10; i++) {
+ if (_fascinWin[i].id != -1) {
+ if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left) &&
+ (_vm->_global->_inter_mouseX < _fascinWin[i].left + _fascinWin[i].width) &&
+ (_vm->_global->_inter_mouseY >= _fascinWin[i].top) &&
+ (_vm->_global->_inter_mouseY < _fascinWin[i].top + _fascinWin[i].height)) {
+
+ if (_fascinWin[i].id == _winCount - 1) {
+ if ((_vm->_global->_inter_mouseX < _fascinWin[i].left + 12) &&
+ (_vm->_global->_inter_mouseY < _fascinWin[i].top + 12) &&
+ (VAR(_winVarArrayStatus / 4 + i) & 2)) {
+
+ blitCursor();
+ activeWin(i);
+ closeWin(i);
+ _vm->_util->waitMouseRelease(1);
+ return i;
+ }
+
+ if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left + _fascinWin[i].width - 12) &&
+ (_vm->_global->_inter_mouseY < _fascinWin[i].top + 12) &&
+ (VAR(_winVarArrayStatus / 4 + i) & 4) &&
+ (_vm->_global->_mousePresent) &&
+ (_vm->_global->_videoMode != 0x07)) {
+
+ blitCursor();
+ handleWinBorder(i);
+ moveWin(i);
+ _vm->_global->_inter_mouseX = _fascinWin[i].left + _fascinWin[i].width - 11;
+ _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+ return -i;
+ }
+ return 0;
+ } else {
+ if (_fascinWin[i].id > bestMatch) {
+ bestMatch = _fascinWin[i].id;
+ matchNum = i;
+ }
+ }
+ }
+ }
+ }
+
+ if (bestMatch != -1) {
+ blitCursor();
+ activeWin(matchNum);
+ }
+
+ return 0;
+}
+
+void Draw_Fascination::moveWin(int16 id) {
+ int oldLeft = _fascinWin[id].left;
+ int oldTop = _fascinWin[id].top;
+
+ restoreWin(id);
+
+ _fascinWin[id].left = _vm->_global->_inter_mouseX;
+ _fascinWin[id].top = _vm->_global->_inter_mouseY;
+
+ WRITE_VAR((_winVarArrayLeft / 4) + id, _fascinWin[id].left);
+ WRITE_VAR((_winVarArrayTop / 4) + id, _fascinWin[id].top);
+
+ saveWin(id);
+
+ // Shift skipped as always set to zero (?)
+ _backSurface->blit(*_frontSurface,
+ oldLeft, oldTop,
+ oldLeft + _fascinWin[id].width - 1,
+ oldTop + _fascinWin[id].height - 1,
+ _fascinWin[id].left, _fascinWin[id].top);
+ invalidateRect(_fascinWin[id].left, _fascinWin[id].top,
+ _fascinWin[id].left + _fascinWin[id].width - 1,
+ _fascinWin[id].top + _fascinWin[id].height - 1);
+}
+
+bool Draw_Fascination::overlapWin(int16 idWin1, int16 idWin2) {
+ if ((_fascinWin[idWin1].left + _fascinWin[idWin1].width <= _fascinWin[idWin2].left) ||
+ (_fascinWin[idWin2].left + _fascinWin[idWin2].width <= _fascinWin[idWin1].left) ||
+ (_fascinWin[idWin1].top + _fascinWin[idWin1].height <= _fascinWin[idWin2].top ) ||
+ (_fascinWin[idWin2].top + _fascinWin[idWin2].height <= _fascinWin[idWin1].top ))
+ return false;
+
+ return true;
+}
+
+void Draw_Fascination::activeWin(int16 id) {
+ bool found = false;
+ int16 t[10], t2[10];
+ int nextId = -1;
+ int oldId = -1;
+ SurfacePtr tempSrf;
+ SurfacePtr oldSrf[10];
+
+ if (_fascinWin[id].id == -1)
+ return;
+
+ blitInvalidated();
+
+ for (int i = 0; i < 10; i++) {
+ t[i] = -1;
+ t2[i] = -1;
+ oldSrf[i].reset();
+ }
+
+ for (int i = 0; i < 10; i++) {
+ if ((i != id) && (_fascinWin[i].id > _fascinWin[id].id) && (overlapWin(i, id))) {
+ t[_fascinWin[i].id] = i;
+ found = true;
+ }
+ }
+
+ if (found) {
+ for (int i = 9; i >= 0; i--) {
+ if (t[i] != -1) {
+ if (nextId != -1)
+ _fascinWin[nextId].savedSurface->blit(*_backSurface,
+ _fascinWin[t[i]].left, _fascinWin[t[i]].top,
+ _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1,
+ _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1,
+ _fascinWin[t[i]].left & 7, 0);
+ t2[i] = nextId;
+ restoreWin(t[i]);
+ nextId = t[i];
+ }
+ }
+
+ oldId = nextId;
+ _fascinWin[nextId].savedSurface->blit(*_backSurface,
+ _fascinWin[id].left, _fascinWin[id].top,
+ _fascinWin[id].left + _fascinWin[id].width - 1,
+ _fascinWin[id].top + _fascinWin[id].height - 1,
+ _fascinWin[id].left & 7, 0);
+ restoreWin(id);
+ nextId = id;
+
+ for (int i = 0; i < 10; i++) {
+ if (t[i] != -1) {
+ _fascinWin[nextId].savedSurface->blit(*_backSurface,
+ _fascinWin[t[i]].left, _fascinWin[t[i]].top,
+ _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1,
+ _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1,
+ _fascinWin[t[i]].left & 7, 0);
+ oldSrf[t[i]] = _fascinWin[nextId].savedSurface;
+ if (t2[i] != -1)
+ _backSurface->blit(*_fascinWin[t2[i]].savedSurface,
+ _fascinWin[t[i]].left & 7, 0,
+ (_fascinWin[t[i]].left & 7) + _fascinWin[t[i]].width - 1,
+ _fascinWin[t[i]].height - 1, _fascinWin[t[i]].left,
+ _fascinWin[t[i]].top);
+ else {
+ // Shift skipped as always set to zero (?)
+ _backSurface->blit(*_frontSurface,
+ _fascinWin[t[i]].left, _fascinWin[t[i]].top,
+ _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1,
+ _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1,
+ _fascinWin[t[i]].left, _fascinWin[t[i]].top);
+ }
+ invalidateRect(_fascinWin[t[i]].left, _fascinWin[t[i]].top,
+ _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1,
+ _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1);
+ nextId = t2[i];
+ }
+ }
+
+ tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 7, _winMaxHeight, 0);
+ tempSrf->blit(*_backSurface,
+ _fascinWin[id].left, _fascinWin[id].top,
+ _fascinWin[id].left + _fascinWin[id].width - 1,
+ _fascinWin[id].top + _fascinWin[id].height - 1,
+ _fascinWin[id].left & 7, 0);
+ _backSurface->blit(*_fascinWin[oldId].savedSurface,
+ _fascinWin[id].left & 7, 0,
+ (_fascinWin[id].left & 7) + _fascinWin[id].width - 1,
+ _fascinWin[id].height - 1,
+ _fascinWin[id].left, _fascinWin[id].top);
+
+ _fascinWin[oldId].savedSurface.reset();
+ _fascinWin[oldId].savedSurface = tempSrf;
+ oldSrf[id] = _fascinWin[oldId].savedSurface;
+
+ invalidateRect(_fascinWin[id].left, _fascinWin[id].top,
+ _fascinWin[id].left + _fascinWin[id].width - 1,
+ _fascinWin[id].top + _fascinWin[id].height - 1);
+ nextId = id;
+
+ for (int j = 0; j < 10; j++) {
+ if (oldSrf[j] != 0)
+ _fascinWin[j].savedSurface = oldSrf[j];
+ }
+ }
+
+ for (int i = 0; i < 10; i++) {
+ if ((i != id) && (_fascinWin[i].id > _fascinWin[id].id))
+ _fascinWin[i].id--;
+ }
+
+ _fascinWin[id].id = _winCount - 1;
+}
+
+void Draw_Fascination::closeAllWin() {
+ for (int i = 0; i < 10; i++) {
+ activeWin(i);
+ closeWin(i);
+ }
+}
+
+void Draw_Fascination::saveWin(int16 id) {
+ _fascinWin[id].savedSurface->blit(*_backSurface,
+ _fascinWin[id].left, _fascinWin[id].top,
+ _fascinWin[id].left + _fascinWin[id].width - 1,
+ _fascinWin[id].top + _fascinWin[id].height - 1,
+ _fascinWin[id].left & 7, 0);
+}
+
+void Draw_Fascination::restoreWin(int16 id) {
+ _backSurface->blit(*_fascinWin[id].savedSurface,
+ _fascinWin[id].left & 7, 0,
+ (_fascinWin[id].left & 7) + _fascinWin[id].width - 1, _fascinWin[id].height - 1,
+ _fascinWin[id].left, _fascinWin[id].top);
+ invalidateRect(_fascinWin[id].left, _fascinWin[id].top,
+ _fascinWin[id].left + _fascinWin[id].width - 1,
+ _fascinWin[id].top + _fascinWin[id].height - 1);
+}
+
+void Draw_Fascination::drawWinTrace(int16 left, int16 top, int16 width, int16 height) {
+ int16 right, bottom;
+
+ right = left + width - 1;
+ bottom = top + height - 1;
+
+ Pixel pixelTop = _frontSurface->get(left, top);
+ Pixel pixelBottom = _frontSurface->get(left, bottom);
+ for (int16 i = 0; i < width; i++, pixelTop++, pixelBottom++) {
+ pixelTop.set((pixelTop.get() + 128) & 0xFF);
+ pixelBottom.set((pixelBottom.get() + 128) & 0xFF);
+ }
+
+ Pixel pixelLeft = _frontSurface->get(left, top);
+ Pixel pixelRight = _frontSurface->get(right, top);
+
+ for (int16 i = 0; i < height; i++, pixelLeft += _frontSurface->getWidth(), pixelRight += _frontSurface->getWidth()) {
+ pixelLeft.set((pixelLeft.get() + 128) & 0xFF);
+ pixelRight.set((pixelRight.get() + 128) & 0xFF);
+ }
+
+ _vm->_video->dirtyRectsAll();
+ _vm->_video->retrace(true);
+}
+
+void Draw_Fascination::handleWinBorder(int16 id) {
+ int16 minX = 0;
+ int16 maxX = 320;
+ int16 minY = 0;
+ int16 maxY = 200;
+
+ if (VAR((_winVarArrayStatus / 4) + id) & 8)
+ minX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) >> 16L);
+ if (VAR((_winVarArrayStatus / 4) + id) & 16)
+ maxX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) & 0xFFFFL);
+ if (VAR((_winVarArrayStatus / 4) + id) & 32)
+ minY = (int16)(VAR((_winVarArrayLimitsY / 4) + id) >> 16L);
+ if (VAR((_winVarArrayStatus / 4) + id) & 64)
+ maxY = (int16)(VAR((_winVarArrayLimitsY / 4) + id) & 0xFFFFL);
+
+ _vm->_global->_inter_mouseX = _fascinWin[id].left;
+ _vm->_global->_inter_mouseY = _fascinWin[id].top;
+
+ if (_vm->_global->_mousePresent)
+ _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+
+ drawWinTrace(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY, _fascinWin[id].width, _fascinWin[id].height);
+ _cursorX = _vm->_global->_inter_mouseX;
+ _cursorY = _vm->_global->_inter_mouseY;
+
+ do {
+ _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 1);
+
+ if (_vm->_global->_inter_mouseX != _cursorX || _vm->_global->_inter_mouseY != _cursorY) {
+ if (_vm->_global->_inter_mouseX < minX) {
+ _vm->_global->_inter_mouseX = minX;
+ if (_vm->_global->_mousePresent)
+ _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+ }
+
+ if (_vm->_global->_inter_mouseY < minY) {
+ _vm->_global->_inter_mouseY = minY;
+ if (_vm->_global->_mousePresent)
+ _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+ }
+
+ if (_vm->_global->_inter_mouseX + _fascinWin[id].width > maxX) {
+ _vm->_global->_inter_mouseX = maxX - _fascinWin[id].width;
+ if (_vm->_global->_mousePresent)
+ _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+ }
+
+ if (_vm->_global->_inter_mouseY + _fascinWin[id].height > maxY) {
+ _vm->_global->_inter_mouseY = maxY - _fascinWin[id].height;
+ if (_vm->_global->_mousePresent)
+ _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+ }
+
+ drawWinTrace(_cursorX, _cursorY, _fascinWin[id].width, _fascinWin[id].height);
+ drawWinTrace(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY, _fascinWin[id].width, _fascinWin[id].height);
+ _cursorX = _vm->_global->_inter_mouseX;
+ _cursorY = _vm->_global->_inter_mouseY;
+ }
+ } while (_vm->_game->_mouseButtons);
+ drawWinTrace(_cursorX, _cursorY, _fascinWin[id].width, _fascinWin[id].height);
+ _cursorX = _vm->_global->_inter_mouseX;
+ _cursorY = _vm->_global->_inter_mouseY;
+}
+
} // End of namespace Gob