Fix a regression in the first part of the intro (gitches when the paper and the rat are moving).

svn-id: r44518
This commit is contained in:
Arnaud Boutonné 2009-10-01 12:19:01 +00:00
parent aba45bfd5f
commit d90c60e879
2 changed files with 193 additions and 91 deletions

View File

@ -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() {}

View File

@ -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;
}
if (_renderFlags & RENDERFLAG_USEDELTAS) {
_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) && !deltaVeto) {
if (_sourceSurface == 21) {
_spriteLeft -= _backDeltaX;
_spriteTop -= _backDeltaY;