From d90c60e879d3e3f9b8a8c76a4b3d82de18698d3c Mon Sep 17 00:00:00 2001 From: Arnaud Boutonné Date: Thu, 1 Oct 2009 12:19:01 +0000 Subject: Fix a regression in the first part of the intro (gitches when the paper and the rat are moving). svn-id: r44518 --- engines/gob/draw.h | 2 +- engines/gob/draw_fascin.cpp | 280 ++++++++++++++++++++++++++++++-------------- 2 files changed, 192 insertions(+), 90 deletions(-) diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 8aca71f494..9ed5ae03b5 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -260,7 +260,7 @@ public: virtual ~Draw_Bargon() {} }; -class Draw_Fascination: public Draw_v1 { +class Draw_Fascination: public Draw_v2 { public: Draw_Fascination(GobEngine *vm); virtual ~Draw_Fascination() {} diff --git a/engines/gob/draw_fascin.cpp b/engines/gob/draw_fascin.cpp index 6a44cdc7f0..9d2ca16ea5 100644 --- a/engines/gob/draw_fascin.cpp +++ b/engines/gob/draw_fascin.cpp @@ -32,15 +32,19 @@ namespace Gob { -Draw_Fascination::Draw_Fascination(GobEngine *vm) : Draw_v1(vm) { +Draw_Fascination::Draw_Fascination(GobEngine *vm) : Draw_v2(vm) { } void Draw_Fascination::spriteOperation(int16 operation) { int16 len; int16 x, y; - int16 perLine; + SurfaceDescPtr sourceSurf, destSurf; + bool deltaVeto; + int16 left; + int16 ratio; Resource *resource; + deltaVeto = (operation & 0x10) != 0; operation &= 0x0F; if (_sourceSurface >= 100) @@ -48,8 +52,8 @@ void Draw_Fascination::spriteOperation(int16 operation) { if (_destSurface >= 100) _destSurface -= 80; - if (_renderFlags & RENDERFLAG_USEDELTAS) { - if (_sourceSurface == 21) { + if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaVeto) { + if ((_sourceSurface == 21) && (operation != DRAW_LOADSPRITE)) { _spriteLeft += _backDeltaX; _spriteTop += _backDeltaY; } @@ -58,8 +62,7 @@ void Draw_Fascination::spriteOperation(int16 operation) { _destSpriteX += _backDeltaX; _destSpriteY += _backDeltaY; if ((operation == DRAW_DRAWLINE) || - ((operation >= DRAW_DRAWBAR) && - (operation <= DRAW_FILLRECTABS))) { + ((operation >= DRAW_DRAWBAR) && (operation <= DRAW_FILLRECTABS))) { _spriteRight += _backDeltaX; _spriteBottom += _backDeltaY; } @@ -72,33 +75,100 @@ void Draw_Fascination::spriteOperation(int16 operation) { return; } } - - Font *font = 0; + + + int16 spriteLeft = _spriteLeft; + int16 spriteTop = _spriteTop; + int16 spriteRight = _spriteRight; + int16 spriteBottom = _spriteBottom; + int16 destSpriteX = _destSpriteX; + int16 destSpriteY = _destSpriteY; + int16 destSurface = _destSurface; + int16 sourceSurface = _sourceSurface; + + if (_vm->_video->_splitSurf && ((_destSurface == 20) || (_destSurface == 21))) { + if ((_destSpriteY >= _vm->_video->_splitStart)) { + _destSpriteY -= _vm->_video->_splitStart; + if ((operation == DRAW_DRAWLINE) || + ((operation >= DRAW_DRAWBAR) && (operation <= DRAW_FILLRECTABS))) + _spriteBottom -= _vm->_video->_splitStart; + + _destSurface += 4; + } + + if ((_spriteTop >= _vm->_video->_splitStart) && (operation == DRAW_BLITSURF)) { + _spriteTop -= _vm->_video->_splitStart; + if (_destSurface < 24) + _destSurface += 4; + } + + } + + adjustCoords(0, &_destSpriteX, &_destSpriteY); + if ((operation != DRAW_LOADSPRITE) && (_needAdjust != 2)) { + adjustCoords(0, &_spriteRight, &_spriteBottom); + adjustCoords(0, &_spriteLeft, &_spriteTop); + + if (operation == DRAW_DRAWLINE) { + if ((_spriteRight == _destSpriteX) || (_spriteBottom == _destSpriteY)) { + operation = DRAW_FILLRECTABS; + _backColor = _frontColor; + } + } else if (operation == DRAW_DRAWLETTER) + operation = DRAW_BLITSURF; + + if (operation == DRAW_DRAWLINE) { + if (_spriteBottom < _destSpriteY) { + SWAP(_spriteBottom, _destSpriteY); + SWAP(_spriteRight, _destSpriteX); + } + } else if ((operation == DRAW_LOADSPRITE) || + (operation > DRAW_PRINTTEXT)) { + if (_spriteBottom < _destSpriteY) + SWAP(_spriteBottom, _destSpriteY); + if (_spriteRight < _destSpriteX) + SWAP(_spriteRight, _destSpriteX); + _spriteRight++; + _spriteBottom++; + } + } + + sourceSurf = _spritesArray[_sourceSurface]; + destSurf = _spritesArray[_destSurface]; + + if (!destSurf) { + warning("Can't do operation %d on surface %d: nonexistent", operation, _destSurface); + return; + } + switch (operation) { + case DRAW_DRAWLETTER: case DRAW_BLITSURF: + if (!sourceSurf || !destSurf) + break; + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], - *_spritesArray[_destSurface], - _spriteLeft, _spriteTop, - _spriteLeft + _spriteRight - 1, - _spriteTop + _spriteBottom - 1, - _destSpriteX, _destSpriteY, _transparency); + *_spritesArray[_destSurface], + _spriteLeft, spriteTop, + _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, + _destSpriteX, _destSpriteY, _transparency); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_PUTPIXEL: - _vm->_video->putPixel(_destSpriteX, _destSpriteY, - _frontColor, *_spritesArray[_destSurface]); + _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, + *_spritesArray[_destSurface]); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY); break; case DRAW_FILLRECT: - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1, _backColor); + _vm->_video->fillRect(*_spritesArray[_destSurface], destSpriteX, + _destSpriteY, _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1, _backColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); @@ -113,6 +183,9 @@ void Draw_Fascination::spriteOperation(int16 operation) { break; case DRAW_INVALIDATE: + _vm->_video->drawCircle(*_spritesArray[_destSurface], _destSpriteX, + _destSpriteY, _spriteRight, _frontColor); + dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, _destSpriteX + _spriteRight, _destSpriteY + _spriteBottom); break; @@ -135,55 +208,110 @@ void Draw_Fascination::spriteOperation(int16 operation) { break; case DRAW_PRINTTEXT: - font = _fonts[_fontIndex]; - if (!font) { - warning("Trying to print \"%s\" with undefined font %d", _textToPrint, _fontIndex); - break; - } - len = strlen(_textToPrint); - dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, - _destSpriteX + len * font->getCharWidth() - 1, - _destSpriteY + font->getCharHeight() - 1); + left = _destSpriteX; - for (int i = 0; i < len; i++) { - _vm->_video->drawLetter(_textToPrint[i], - _destSpriteX, _destSpriteY, - *font, _transparency, - _frontColor, _backColor, - *_spritesArray[_destSurface]); + if ((_fontIndex >= 4) || (_fontToSprite[_fontIndex].sprite == -1)) { + Font *font = _fonts[_fontIndex]; + if (!font) { + warning("Trying to print \"%s\" with undefined font %d", _textToPrint, _fontIndex); + break; + } - _destSpriteX += font->getCharWidth(); + if (font->isMonospaced()) { + if (((int8) _textToPrint[0]) == -1) { + _vm->validateLanguage(); + + 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]); + } + } else { + drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, + _backColor, _transparency, *_spritesArray[_destSurface], *font); + _destSpriteX += len * font->getCharWidth(); + } + } else { + for (int i = 0; i < len; i++) { + _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, + _destSpriteY, *font, _transparency, + _frontColor, _backColor, *_spritesArray[_destSurface]); + _destSpriteX += font->getCharWidth(_textToPrint[i]); + } + } + + } else { + sourceSurf = _spritesArray[_fontToSprite[_fontIndex].sprite]; + ratio = ((sourceSurf == _frontSurface) || (sourceSurf == _backSurface)) ? + 320 : sourceSurf->getWidth(); + ratio /= _fontToSprite[_fontIndex].width; + for (int i = 0; i < len; i++) { + y = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) / ratio) + * _fontToSprite[_fontIndex].height; + x = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) % ratio) + * _fontToSprite[_fontIndex].width; + _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], + *_spritesArray[_destSurface], x, y, + x + _fontToSprite[_fontIndex].width - 1, + y + _fontToSprite[_fontIndex].height - 1, + _destSpriteX, _destSpriteY, _transparency); + _destSpriteX += _fontToSprite[_fontIndex].width; + } } + + dirtiedRect(_destSurface, left, _destSpriteY, + _destSpriteX - 1, _destSpriteY + _fonts[_fontIndex]->getCharHeight() - 1); break; case DRAW_DRAWBAR: - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _spriteBottom, - _spriteRight, _spriteBottom, _frontColor); + if (_needAdjust != 2) { + _vm->_video->fillRect(*_spritesArray[_destSurface], + _destSpriteX, _spriteBottom - 1, + _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, - _destSpriteX, _spriteBottom, _frontColor); + _vm->_video->fillRect(*_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _destSpriteX + 1, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _spriteRight, _destSpriteY, - _spriteRight, _spriteBottom, _frontColor); + _vm->_video->fillRect(*_spritesArray[_destSurface], + _spriteRight - 1, _destSpriteY, + _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, - _spriteRight, _destSpriteY, _frontColor); + _vm->_video->fillRect(*_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _spriteRight, _destSpriteY + 1, _frontColor); + } else { + _vm->_video->drawLine(*_spritesArray[_destSurface], + _destSpriteX, _spriteBottom, + _spriteRight, _spriteBottom, _frontColor); + + _vm->_video->drawLine(*_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _destSpriteX, _spriteBottom, _frontColor); + + _vm->_video->drawLine(*_spritesArray[_destSurface], + _spriteRight, _destSpriteY, + _spriteRight, _spriteBottom, _frontColor); + + _vm->_video->drawLine(*_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _spriteRight, _destSpriteY, _frontColor); + } dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_CLEARRECT: - if (_backColor < 16) { + if ((_backColor != 16) && (_backColor != 144)) { _vm->_video->fillRect(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; @@ -194,50 +322,24 @@ void Draw_Fascination::spriteOperation(int16 operation) { dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; + } - case DRAW_DRAWLETTER: - font = _fonts[_fontIndex]; - if (!font) { - warning("Trying to print \'%c\' with undefined font %d", _letterToPrint, _fontIndex); - break; - } - - if (_fontToSprite[_fontIndex].sprite == -1) { - dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, - _destSpriteX + font->getCharWidth() - 1, - _destSpriteY + font->getCharHeight() - 1); - _vm->_video->drawLetter(_letterToPrint, - _destSpriteX, _destSpriteY, - *font, _transparency, - _frontColor, _backColor, - *_spritesArray[_destSurface]); - break; - } - - perLine = - _spritesArray[(int16)_fontToSprite[_fontIndex].sprite]->getWidth() / - _fontToSprite[_fontIndex].width; - - y = (_letterToPrint - _fontToSprite[_fontIndex].base) / perLine * - _fontToSprite[_fontIndex].height; - - x = (_letterToPrint - _fontToSprite[_fontIndex].base) % perLine * - _fontToSprite[_fontIndex].width; - - dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, - _destSpriteX + _fontToSprite[_fontIndex].width, - _destSpriteY + _fontToSprite[_fontIndex].height); - - _vm->_video->drawSprite(*_spritesArray[(int16)_fontToSprite[_fontIndex].sprite], - *_spritesArray[_destSurface], x, y, - x + _fontToSprite[_fontIndex].width, - y + _fontToSprite[_fontIndex].height, - _destSpriteX, _destSpriteY, _transparency); - - break; + _spriteLeft = spriteLeft; + _spriteTop = spriteTop; + _spriteRight = spriteRight; + _spriteBottom = spriteBottom; + _destSpriteX = destSpriteX; + _destSpriteY = destSpriteY; + _destSurface = destSurface; + _sourceSurface = sourceSurface; + + if (operation == DRAW_PRINTTEXT) { + len = _fonts[_fontIndex]->getCharWidth(); + adjustCoords(1, &len, 0); + _destSpriteX += len * strlen(_textToPrint); } - if (_renderFlags & RENDERFLAG_USEDELTAS) { + if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaVeto) { if (_sourceSurface == 21) { _spriteLeft -= _backDeltaX; _spriteTop -= _backDeltaY; -- cgit v1.2.3