From 5cd3ea41db71b4521954cd65bc9775c1bbeabb9f Mon Sep 17 00:00:00 2001 From: Arnaud Boutonné Date: Sat, 21 Aug 2010 18:16:04 +0000 Subject: GOB: Clean up of Fascination code Move Fascination specific function to appropriate classes, plus some style modifications svn-id: r52267 --- engines/gob/draw.cpp | 768 ------------------------------------------- engines/gob/draw.h | 41 ++- engines/gob/draw_fascin.cpp | 777 +++++++++++++++++++++++++++++++++++++++++++- engines/gob/game.cpp | 6 +- engines/gob/hotspots.cpp | 33 +- engines/gob/init_fascin.cpp | 9 +- engines/gob/inter.cpp | 2 +- engines/gob/sound/sound.cpp | 8 +- 8 files changed, 831 insertions(+), 813 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 0f5c5d83b2..62b9a5e630 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -530,774 +530,6 @@ void Draw::oPlaytoons_sub_F_1B(uint16 id, int16 left, int16 top, int16 right, in return; } -void Draw::activeWin(int16 id) { - bool found = false; - int16 t[10], t2[10]; - int nextId = -1; - int oldId = -1; - SurfaceDescPtr tempSrf; - SurfaceDescPtr 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) && (winOverlap(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) - _vm->_video->drawSprite(*_backSurface, *_fascinWin[nextId].savedSurface, - _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, 0); - t2[i] = nextId; - restoreWin(t[i]); - nextId = t[i]; - } - } - - oldId = nextId; - _vm->_video->drawSprite(*_backSurface, *_fascinWin[nextId].savedSurface, - _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, 0); - restoreWin(id); - nextId = id; - - for (int i = 0; i < 10; i++) { - if (t[i] != -1) { - _vm->_video->drawSprite(*_backSurface, *_fascinWin[nextId].savedSurface, - _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, 0); - oldSrf[t[i]] = _fascinWin[nextId].savedSurface; - if (t2[i] != -1) - _vm->_video->drawSprite(*_fascinWin[t2[i]].savedSurface, *_backSurface, - _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, 0); - else { - // Shift skipped as always set to zero (?) - _vm->_video->drawSprite(*_frontSurface, *_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, _fascinWin[t[i]].top, 0); - } - 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); - _vm->_video->drawSprite(*_backSurface, *tempSrf, - _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, 0); - _vm->_video->drawSprite(*_fascinWin[oldId].savedSurface, *_backSurface, - _fascinWin[id].left & 7, 0, - (_fascinWin[id].left & 7) + _fascinWin[id].width - 1, - _fascinWin[id].height - 1, - _fascinWin[id].left, _fascinWin[id].top, 0); - - _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; -} - -bool Draw::winOverlap(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::closeWin(int16 i) { - if (_fascinWin[i].id == -1) - return; - - WRITE_VAR((_winVarArrayStatus / 4) + i, VAR((_winVarArrayStatus / 4) + i) | 1); - restoreWin(i); - _fascinWin[i].id = -1; - _fascinWin[i].savedSurface.reset(); - _winCount--; -} - -void Draw::closeAllWin() { - for (int i = 0; i < 10; i++){ - activeWin(i); - closeWin(i); - } -} - -int16 Draw::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; -} - -void Draw::restoreWin(int16 i) { - _vm->_video->drawSprite(*_fascinWin[i].savedSurface, *_backSurface, - _fascinWin[i].left & 7, 0, - (_fascinWin[i].left & 7) + _fascinWin[i].width - 1, _fascinWin[i].height - 1, - _fascinWin[i].left, _fascinWin[i].top, 0); - invalidateRect(_fascinWin[i].left, _fascinWin[i].top, - _fascinWin[i].left + _fascinWin[i].width - 1, - _fascinWin[i].top + _fascinWin[i].height - 1); -} - -void Draw::saveWin(int16 id) { - _vm->_video->drawSprite(*_backSurface, *_fascinWin[id].savedSurface, - _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, 0); -} - -void Draw::winMove(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 (?) - _vm->_video->drawSprite(*_frontSurface, *_backSurface, - oldLeft, oldTop, - oldLeft + _fascinWin[id].width - 1, - oldTop + _fascinWin[id].height - 1, - _fascinWin[id].left, _fascinWin[id].top, 0); - invalidateRect(_fascinWin[id].left, _fascinWin[id].top, - _fascinWin[id].left + _fascinWin[id].width - 1, - _fascinWin[id].top + _fascinWin[id].height - 1); -} - -void Draw::winTrace(int16 left, int16 top, int16 width, int16 height) { - int16 right, bottom; - - right = left + width - 1; - bottom = top + height - 1; - - - for(int32 x = left; x < right; x++ ) { - _frontSurface->getVidMem()[_frontSurface->getWidth() * top + x] = (128 + _frontSurface->getVidMem()[_frontSurface->getWidth() * top + x]) & 0xff; - _frontSurface->getVidMem()[_frontSurface->getWidth() * bottom + x] = (128 + _frontSurface->getVidMem()[_frontSurface->getWidth() * bottom + x]) & 0xff; - } - - for(int32 y = top; y < bottom; y++ ) { - _frontSurface->getVidMem()[_frontSurface->getWidth() * y + left] = (128 + _frontSurface->getVidMem()[_frontSurface->getWidth() * y + left]) & 0xff; - _frontSurface->getVidMem()[_frontSurface->getWidth() * y + right] = (128 + _frontSurface->getVidMem()[_frontSurface->getWidth() * y + right]) & 0xff; - } - - _vm->_video->dirtyRectsAll(); - _vm->_video->retrace(true); -} - -void Draw::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); - - winTrace(_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); - } - - winTrace(_cursorX, _cursorY, _fascinWin[id].width, _fascinWin[id].height); - winTrace(_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); - winTrace(_cursorX, _cursorY, _fascinWin[id].width, _fascinWin[id].height); - _cursorX = _vm->_global->_inter_mouseX; - _cursorY = _vm->_global->_inter_mouseY; -} - -int16 Draw::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); - winMove(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::winDecomp(int16 x, int16 y, SurfaceDescPtr 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; -} - -void Draw::winDraw(int16 fct) { - int16 left; - int16 top; - int16 width; - int16 height; - - bool found = false; - int len; - Resource *resource; - int table[10]; - SurfaceDescPtr 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: -// width = 0; -// height = 0; - 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)) { - _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_spritesArray[_destSurface], - _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, - _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, _transparency); - 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]) - _vm->_video->drawSprite(*_fascinWin[table[i]].savedSurface, *_spritesArray[_destSurface], - _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, 0); - } - return; - } - - if (found) { - tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width - left + 1, height - top + 1, 0); - _vm->_video->drawSprite(*_backSurface, *tempSrf, left, top, width, height, 0, 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]) - _vm->_video->drawSprite(*_fascinWin[table[i]].savedSurface, *tempSrf, - _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 , 0); - } - - invalidateRect(left, top, width, height); - - switch (fct) { - case DRAW_BLITSURF: // 0 - move - _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *tempSrf, - _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, - _spriteTop + _spriteBottom - 1, 0, 0, _transparency); - break; - - case DRAW_PUTPIXEL: // 1 - put a pixel - _vm->_video->putPixel(0, 0, _frontColor, *tempSrf); - break; - - case DRAW_FILLRECT: // 2 - fill rectangle - _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - 1, _spriteBottom - 1, _backColor); - break; - - case DRAW_DRAWLINE: // 3 - draw line - _vm->_video->drawLine(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); - break; - - case DRAW_INVALIDATE: // 4 - Draw a circle - _vm->_video->drawCircle(*tempSrf, _spriteRight, _spriteRight, _spriteRight, _frontColor); - break; - - case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite - winDecomp(0, 0, tempSrf); - break; - - case DRAW_PRINTTEXT: // 6 - Display string - len = strlen(_textToPrint); - for (int j = 0; j < len; j++) - _vm->_video->drawLetter(_textToPrint[j], j * _fonts[_fontIndex]->getCharWidth(), 0, - *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *tempSrf); - _destSpriteX += len * _fonts[_fontIndex]->getCharWidth(); - break; - - case DRAW_DRAWBAR: // 7 - draw border - _vm->_video->drawLine(*tempSrf, 0, _spriteBottom - _destSpriteY, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); - _vm->_video->drawLine(*tempSrf, 0, 0, 0, _spriteBottom - _destSpriteY, _frontColor); - _vm->_video->drawLine(*tempSrf, _spriteRight - _destSpriteX, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); - _vm->_video->drawLine(*tempSrf, 0, 0, _spriteRight - _destSpriteX, 0, _frontColor); - break; - - case DRAW_CLEARRECT: // 8 - clear rectangle - if (_backColor < 16) - _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor); - break; - - case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates - _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor); - break; - - case DRAW_DRAWLETTER: // 10 - Display a character - if (_fontToSprite[_fontIndex].sprite == -1) { - - if (_letterToPrint) - _vm->_video->drawLetter(_letterToPrint, 0, 0, *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *tempSrf); - } 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; - _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], *tempSrf, - xx, yy, xx + _fontToSprite[_fontIndex].width - 1, - yy + _fontToSprite[_fontIndex].height - 1, 0, 0, _transparency); - } - 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]; - _vm->_video->drawSprite(*tempSrf, *_fascinWin[k].savedSurface, - 0, 0, width - left, height - top, - left - _fascinWin[k].left + (_fascinWin[k].left & 7), - top - _fascinWin[k].top, 0); - // Shift skipped as always set to zero (?) - _vm->_video->drawSprite(*_frontSurface, *tempSrf, - 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, 0); - if (_cursorIndex != -1) - _vm->_video->drawSprite(*_cursorSpritesBack, *tempSrf, - 0, 0, _cursorWidth - 1, _cursorHeight - 1, - _cursorX - left, _cursorY - top, 0); - for (int j = 9; j > i; j--) { - if (table[j] && winOverlap(k, table[j])) { - int l = table[j]; - _vm->_video->drawSprite(*_fascinWin[l].savedSurface, *tempSrf, - 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, 0); - } - } - } - } - _vm->_video->drawSprite(*tempSrf, *_backSurface, 0, 0, width - left, height - top, left, top, 0); - tempSrf.reset(); - } else { - invalidateRect(left, top, width, height); - switch (fct) { - case DRAW_BLITSURF: // 0 - move - _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_backSurface, - _spriteLeft, _spriteTop, - _spriteLeft + _spriteRight - 1, - _spriteTop + _spriteBottom - 1, - _destSpriteX, _destSpriteY, _transparency); - break; - case DRAW_PUTPIXEL: // 1 - put a pixel - _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, *_backSurface); - break; - - case DRAW_FILLRECT: // 2 - fill rectangle - _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); - break; - - case DRAW_DRAWLINE: // 3 - draw line - _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - break; - - case DRAW_INVALIDATE: // 4 - Draw a circle - _vm->_video->drawCircle(*_backSurface, _spriteRight, _spriteRight, _spriteRight, _frontColor); - break; - - case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite - winDecomp(_destSpriteX, _destSpriteY, _backSurface); - break; - - case DRAW_PRINTTEXT: // 6 - Display string - len = strlen(_textToPrint); - for (int j = 0; j < len; j++) - _vm->_video->drawLetter(_textToPrint[j], _destSpriteX + j * _fonts[_fontIndex]->getCharWidth(), - _destSpriteY, *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *_backSurface); - _destSpriteX += len * _fonts[_fontIndex]->getCharWidth(); - break; - - case DRAW_DRAWBAR: // 7 - draw border - _vm->_video->drawLine(*_backSurface, _destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_backSurface, _spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); - break; - - case DRAW_CLEARRECT: // 8 - clear rectangle - if (_backColor < 16) - _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); - break; - - case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates - _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); - break; - - case DRAW_DRAWLETTER: // 10 - Display a character - if (_fontToSprite[_fontIndex].sprite == -1) { - if (_letterToPrint) - _vm->_video->drawLetter(_letterToPrint, _destSpriteX, _destSpriteY, *_fonts[_fontIndex], _transparency, - _frontColor, _backColor, *_spritesArray[_destSurface]); - } 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; - _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], *_spritesArray[_destSurface], - xx, yy, - xx + _fontToSprite[_fontIndex].width - 1, - yy + _fontToSprite[_fontIndex].height - 1, - _destSpriteX, _destSpriteY, _transparency); - } - 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; - } -} - -int16 Draw::isOverWin(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); -} int32 Draw::getSpriteRectSize(int16 index) { if (!_spritesArray[index]) return 0; diff --git a/engines/gob/draw.h b/engines/gob/draw.h index fa3cbb84cc..cbadde8e27 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -192,21 +192,6 @@ public: int16 bottom, const char *str, int16 fontIndex, int16 color); void oPlaytoons_sub_F_1B( uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *paramStr, int16 var3, int16 var4, int16 shortId); - int16 openWin(int16 id); - int16 handleCurWin(); - bool winOverlap(int16 idWin1, int16 idWin2); - void winDecomp(int16 x, int16 y, SurfaceDescPtr destPtr); - void activeWin(int16 id); - void closeWin(int16 id); - void closeAllWin(); - void restoreWin(int16 i); - void saveWin(int16 id); - void winMove(int16 id); - void handleWinBorder(int16 id); - void winDraw(int16 fct); - void winTrace(int16 left, int16 top, int16 width, int16 height); - int16 isOverWin(int16 &dx, int16 &dy); - int32 getSpriteRectSize(int16 index); void forceBlit(bool backwards = false); @@ -223,6 +208,15 @@ public: virtual void printTotText(int16 id) = 0; virtual void spriteOperation(int16 operation) = 0; + virtual int16 openWin(int16 id) { return 0; } + virtual void closeWin(int16 id) {} + virtual int16 handleCurWin() { return 0; } + virtual int16 getWinFromCoord(int16 &dx, int16 &dy) { return -1; } + virtual void moveWin(int16 id) {} + virtual bool overlapWin(int16 idWin1, int16 idWin2) { return false; } + virtual void closeAllWin() {} + virtual void activeWin(int16 id) {} + Draw(GobEngine *vm); virtual ~Draw(); @@ -272,6 +266,23 @@ public: Draw_Fascination(GobEngine *vm); virtual ~Draw_Fascination() {} virtual void spriteOperation(int16 operation); + + void decompWin(int16 x, int16 y, SurfaceDescPtr destPtr); + void drawWin(int16 fct); + void saveWin(int16 id); + void restoreWin(int16 id); + void handleWinBorder(int16 id); + void drawWinTrace(int16 left, int16 top, int16 width, int16 height); + + virtual int16 openWin(int16 id); + virtual void closeWin(int16 id); + virtual int16 getWinFromCoord(int16 &dx, int16 &dy); + virtual int16 handleCurWin(); + virtual void activeWin(int16 id); + virtual void moveWin(int16 id); + virtual bool overlapWin(int16 idWin1, int16 idWin2); + virtual void closeAllWin(); + }; class Draw_Playtoons: public Draw_v2 { diff --git a/engines/gob/draw_fascin.cpp b/engines/gob/draw_fascin.cpp index 1e01db7dfb..dcb76d722c 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 { @@ -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; } } @@ -352,4 +354,777 @@ 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]; + SurfaceDescPtr 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)) { + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_spritesArray[_destSurface], + _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, _transparency); + 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]) + _vm->_video->drawSprite(*_fascinWin[table[i]].savedSurface, *_spritesArray[_destSurface], + _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, 0); + } + return; + } + + if (found) { + tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width - left + 1, height - top + 1, 0); + _vm->_video->drawSprite(*_backSurface, *tempSrf, left, top, width, height, 0, 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]) + _vm->_video->drawSprite(*_fascinWin[table[i]].savedSurface, *tempSrf, + _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 , 0); + } + + invalidateRect(left, top, width, height); + + switch (fct) { + case DRAW_BLITSURF: // 0 - move + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *tempSrf, + _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, 0, 0, _transparency); + break; + + case DRAW_PUTPIXEL: // 1 - put a pixel + _vm->_video->putPixel(0, 0, _frontColor, *tempSrf); + break; + + case DRAW_FILLRECT: // 2 - fill rectangle + _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - 1, _spriteBottom - 1, _backColor); + break; + + case DRAW_DRAWLINE: // 3 - draw line + _vm->_video->drawLine(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); + break; + + case DRAW_INVALIDATE: // 4 - Draw a circle + _vm->_video->drawCircle(*tempSrf, _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++) + _vm->_video->drawLetter(_textToPrint[j], j * _fonts[_fontIndex]->getCharWidth(), 0, + *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *tempSrf); + _destSpriteX += len * _fonts[_fontIndex]->getCharWidth(); + break; + + case DRAW_DRAWBAR: // 7 - draw border + _vm->_video->drawLine(*tempSrf, 0, _spriteBottom - _destSpriteY, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); + _vm->_video->drawLine(*tempSrf, 0, 0, 0, _spriteBottom - _destSpriteY, _frontColor); + _vm->_video->drawLine(*tempSrf, _spriteRight - _destSpriteX, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); + _vm->_video->drawLine(*tempSrf, 0, 0, _spriteRight - _destSpriteX, 0, _frontColor); + break; + + case DRAW_CLEARRECT: // 8 - clear rectangle + if (_backColor < 16) + _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor); + break; + + case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates + _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor); + break; + + case DRAW_DRAWLETTER: // 10 - Display a character + if (_fontToSprite[_fontIndex].sprite == -1) { + + if (_letterToPrint) + _vm->_video->drawLetter(_letterToPrint, 0, 0, *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *tempSrf); + } 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; + _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], *tempSrf, + xx, yy, xx + _fontToSprite[_fontIndex].width - 1, + yy + _fontToSprite[_fontIndex].height - 1, 0, 0, _transparency); + } + 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]; + _vm->_video->drawSprite(*tempSrf, *_fascinWin[k].savedSurface, + 0, 0, width - left, height - top, + left - _fascinWin[k].left + (_fascinWin[k].left & 7), + top - _fascinWin[k].top, 0); + // Shift skipped as always set to zero (?) + _vm->_video->drawSprite(*_frontSurface, *tempSrf, + 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, 0); + if (_cursorIndex != -1) + _vm->_video->drawSprite(*_cursorSpritesBack, *tempSrf, + 0, 0, _cursorWidth - 1, _cursorHeight - 1, + _cursorX - left, _cursorY - top, 0); + for (int j = 9; j > i; j--) { + if (table[j] && overlapWin(k, table[j])) { + int l = table[j]; + _vm->_video->drawSprite(*_fascinWin[l].savedSurface, *tempSrf, + 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, 0); + } + } + } + } + _vm->_video->drawSprite(*tempSrf, *_backSurface, 0, 0, width - left, height - top, left, top, 0); + tempSrf.reset(); + } else { + invalidateRect(left, top, width, height); + switch (fct) { + case DRAW_BLITSURF: // 0 - move + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_backSurface, + _spriteLeft, _spriteTop, + _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, + _destSpriteX, _destSpriteY, _transparency); + break; + case DRAW_PUTPIXEL: // 1 - put a pixel + _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, *_backSurface); + break; + + case DRAW_FILLRECT: // 2 - fill rectangle + _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); + break; + + case DRAW_DRAWLINE: // 3 - draw line + _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); + break; + + case DRAW_INVALIDATE: // 4 - Draw a circle + _vm->_video->drawCircle(*_backSurface, _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++) + _vm->_video->drawLetter(_textToPrint[j], _destSpriteX + j * _fonts[_fontIndex]->getCharWidth(), + _destSpriteY, *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *_backSurface); + _destSpriteX += len * _fonts[_fontIndex]->getCharWidth(); + break; + + case DRAW_DRAWBAR: // 7 - draw border + _vm->_video->drawLine(*_backSurface, _destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); + _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); + _vm->_video->drawLine(*_backSurface, _spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); + _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); + break; + + case DRAW_CLEARRECT: // 8 - clear rectangle + if (_backColor < 16) + _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); + break; + + case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates + _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); + break; + + case DRAW_DRAWLETTER: // 10 - Display a character + if (_fontToSprite[_fontIndex].sprite == -1) { + if (_letterToPrint) + _vm->_video->drawLetter(_letterToPrint, _destSpriteX, _destSpriteY, *_fonts[_fontIndex], _transparency, + _frontColor, _backColor, *_spritesArray[_destSurface]); + } 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; + _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], *_spritesArray[_destSurface], + xx, yy, + xx + _fontToSprite[_fontIndex].width - 1, + yy + _fontToSprite[_fontIndex].height - 1, + _destSpriteX, _destSpriteY, _transparency); + } + 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, SurfaceDescPtr 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 (?) + _vm->_video->drawSprite(*_frontSurface, *_backSurface, + oldLeft, oldTop, + oldLeft + _fascinWin[id].width - 1, + oldTop + _fascinWin[id].height - 1, + _fascinWin[id].left, _fascinWin[id].top, 0); + 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; + SurfaceDescPtr tempSrf; + SurfaceDescPtr 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) + _vm->_video->drawSprite(*_backSurface, *_fascinWin[nextId].savedSurface, + _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, 0); + t2[i] = nextId; + restoreWin(t[i]); + nextId = t[i]; + } + } + + oldId = nextId; + _vm->_video->drawSprite(*_backSurface, *_fascinWin[nextId].savedSurface, + _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, 0); + restoreWin(id); + nextId = id; + + for (int i = 0; i < 10; i++) { + if (t[i] != -1) { + _vm->_video->drawSprite(*_backSurface, *_fascinWin[nextId].savedSurface, + _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, 0); + oldSrf[t[i]] = _fascinWin[nextId].savedSurface; + if (t2[i] != -1) + _vm->_video->drawSprite(*_fascinWin[t2[i]].savedSurface, *_backSurface, + _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, 0); + else { + // Shift skipped as always set to zero (?) + _vm->_video->drawSprite(*_frontSurface, *_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, _fascinWin[t[i]].top, 0); + } + 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); + _vm->_video->drawSprite(*_backSurface, *tempSrf, + _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, 0); + _vm->_video->drawSprite(*_fascinWin[oldId].savedSurface, *_backSurface, + _fascinWin[id].left & 7, 0, + (_fascinWin[id].left & 7) + _fascinWin[id].width - 1, + _fascinWin[id].height - 1, + _fascinWin[id].left, _fascinWin[id].top, 0); + + _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) { + _vm->_video->drawSprite(*_backSurface, *_fascinWin[id].savedSurface, + _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, 0); +} + +void Draw_Fascination::restoreWin(int16 id) { + _vm->_video->drawSprite(*_fascinWin[id].savedSurface, *_backSurface, + _fascinWin[id].left & 7, 0, + (_fascinWin[id].left & 7) + _fascinWin[id].width - 1, _fascinWin[id].height - 1, + _fascinWin[id].left, _fascinWin[id].top, 0); + 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; + + for (int32 x = left; x < right; x++) { + _frontSurface->getVidMem()[_frontSurface->getWidth() * top + x] = (128 + _frontSurface->getVidMem()[_frontSurface->getWidth() * top + x]) & 0xff; + _frontSurface->getVidMem()[_frontSurface->getWidth() * bottom + x] = (128 + _frontSurface->getVidMem()[_frontSurface->getWidth() * bottom + x]) & 0xff; + } + + for (int32 y = top; y < bottom; y++) { + _frontSurface->getVidMem()[_frontSurface->getWidth() * y + left] = (128 + _frontSurface->getVidMem()[_frontSurface->getWidth() * y + left]) & 0xff; + _frontSurface->getVidMem()[_frontSurface->getWidth() * y + right] = (128 + _frontSurface->getVidMem()[_frontSurface->getWidth() * y + right]) & 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 diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 1a8823b156..b5025ba76f 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -215,7 +215,7 @@ void Game::prepareStart() { _vm->_draw->initScreen(); _vm->_video->fillRect(*_vm->_draw->_frontSurface, 0, 0, - _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 1); + _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 1); _vm->_util->setMousePos(152, 92); _vm->_draw->_cursorX = _vm->_global->_inter_mouseX = 152; @@ -352,8 +352,8 @@ void Game::playTot(int16 skipPlay) { } } - if (_vm->getGameType() == kGameTypeFascination) - _vm->_draw->closeAllWin(); + _vm->_draw->closeAllWin(); + if (_totToLoad[0] == 0) break; diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp index ba0a65f4d4..78b3553aeb 100644 --- a/engines/gob/hotspots.cpp +++ b/engines/gob/hotspots.cpp @@ -431,9 +431,10 @@ void Hotspots::pop() { // Find the end of the filled hotspot space int i; Hotspot *destPtr = _hotspots; - for (i = 0; i < kHotspotCount; i++, destPtr++) + for (i = 0; i < kHotspotCount; i++, destPtr++) { if (destPtr->isEnd()) break; + } if (((uint32) (kHotspotCount - i)) < backup.size) error("Hotspots::pop(): Not enough free space in the current Hotspot " @@ -525,12 +526,12 @@ void Hotspots::leave(uint16 index) { int16 Hotspots::curWindow(int16 &dx, int16 &dy) const { if ((_vm->_draw->_renderFlags & 0x80)==0) return(0); - for (int i = 0; i < 10; i++) - if (_vm->_draw->_fascinWin[i].id != -1) + for (int i = 0; i < 10; i++) { + if (_vm->_draw->_fascinWin[i].id != -1) { if (_vm->_global->_inter_mouseX >= _vm->_draw->_fascinWin[i].left && _vm->_global->_inter_mouseX < _vm->_draw->_fascinWin[i].left + _vm->_draw->_fascinWin[i].width && _vm->_global->_inter_mouseY >= _vm->_draw->_fascinWin[i].top && - _vm->_global->_inter_mouseY < _vm->_draw->_fascinWin[i].top + _vm->_draw->_fascinWin[i].height) + _vm->_global->_inter_mouseY < _vm->_draw->_fascinWin[i].top + _vm->_draw->_fascinWin[i].height) { if (_vm->_draw->_fascinWin[i].id == _vm->_draw->_winCount-1) { dx = _vm->_draw->_fascinWin[i].left; dy = _vm->_draw->_fascinWin[i].top; @@ -546,6 +547,9 @@ int16 Hotspots::curWindow(int16 &dx, int16 &dy) const { return(6); return(-i); } + } + } + } return(0); } @@ -555,10 +559,7 @@ uint16 Hotspots::checkMouse(Type type, uint16 &id, uint16 &index) const { int16 dx = 0; int16 dy = 0; - int16 winId = -1; - - if (_vm->getGameType() == kGameTypeFascination) - winId = _vm->_draw->isOverWin(dx, dy); + int16 winId = _vm->_draw->getWinFromCoord(dx, dy); if (winId < 0) { winId = 0; @@ -753,11 +754,8 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index if (_vm->_game->_mouseButtons != kMouseButtonsNone) { // Mouse button pressed - int i; - if (_vm->getGameType() == kGameTypeFascination) - i = _vm->_draw->handleCurWin(); - else - i = 0; + int i = _vm->_draw->handleCurWin(); + if (!i) { _vm->_draw->animateCursor(2); if (delay > 0) { @@ -1242,7 +1240,7 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left, top + height - 1, 0); _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left + width - 1, top, 0); _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top + height - 1, left + width - 1, top + height - 1, 0); - } else + } else { if ((_vm->_draw->_fascinWin[windowNum].id != -1) && (_vm->_draw->_fascinWin[windowNum].id == _vm->_draw->_winCount - 1)) { left += _vm->_draw->_fascinWin[windowNum].left; top += _vm->_draw->_fascinWin[windowNum].top; @@ -1253,6 +1251,7 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, left -= _vm->_draw->_fascinWin[windowNum].left; top -= _vm->_draw->_fascinWin[windowNum].top; } + } } type &= 0x7F; @@ -1721,9 +1720,9 @@ void Hotspots::oPlaytoons_F_1B() { // var_4 += unk_var; for (int i = 0; i < kHotspotCount; i++) { - if (_hotspots[i].isEnd()) { + if (_hotspots[i].isEnd()) return; - } + if ((_hotspots[i].id == 0xD000 + shortId) || (_hotspots[i].id == 0xB000 + shortId) || (_hotspots[i].id == 0x4000 + shortId)) { longId = _hotspots[i].id; @@ -1744,7 +1743,6 @@ void Hotspots::oPlaytoons_F_1B() { right -= 2; bottom -= 2; } -// oPlaytoons_sub_F_1B(0x8000 + var2, left, top, right, bottom, _vm->_game->_script->getResultStr(), var3, var4, shortId); _vm->_draw->oPlaytoons_sub_F_1B(0x8000+ var2, left, top, right, bottom, _vm->_game->_script->getResultStr(), fontIndex, var4, shortId); return; } @@ -2052,7 +2050,6 @@ void Hotspots::matchInputStrings(const InputDesc *inputs) const { cleanFloatString(spot); if ((spot.getType() >= kTypeInput2NoLeave) && (spot.getType() <= kTypeInput3Leave)) { - // Look if we find a match between the wanted and the typed string checkStringMatch(spot, inputs[inputIndex], inputPos); strInputCount++; diff --git a/engines/gob/init_fascin.cpp b/engines/gob/init_fascin.cpp index f853858564..9842b7e752 100644 --- a/engines/gob/init_fascin.cpp +++ b/engines/gob/init_fascin.cpp @@ -41,14 +41,15 @@ Init_Fascination::~Init_Fascination() { void Init_Fascination::updateConfig() { // In Fascination, some empty texts are present and used to clean up the text area. // Using _doSubtitles does the trick. -// The first obvious example is in the hotel hall: 'Use ...' is displayed at the same -// place than the character dialogs. +// The first obvious example is in the hotel hall: 'Use ...' is displayed at +// the same place than the character dialogs. _vm->_global->_doSubtitles = true; } void Init_Fascination::initGame() { - // HACK - Suppress ADLIB_FLAG as the MDY/TBR player is not working. suppress the honker too, - // as the script checks in the intro for it's presence to play or not some noices. +// HACK - Suppress ADLIB_FLAG as the MDY/TBR player is not working. suppress +// the PC Speaker too, as the script checks in the intro for it's presence +// to play or not some noices. _vm->_global->_soundFlags = MIDI_FLAG | BLASTER_FLAG; Init::initGame(); diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index 3141d618bd..256ca37e50 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -292,7 +292,7 @@ void Inter::funcBlock(int16 retFlag) { // WORKAROUND: // The Amiga and Atari ST versions of Fascination don't add a delay after - // showing images between some levels, probably using the loading time int account. + // showing images between some levels, probably using the loading time int account. // We manually add it here. if ((_vm->getGameType() == kGameTypeFascination) && ((_vm->getPlatform() == Common::kPlatformAmiga)|| diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index 5abc94d025..bc4495fafd 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -610,11 +610,13 @@ void Sound::cdPlayMultMusic() { void Sound::cdPlay(const char *trackName) { if (!_cdrom) return; - debugC(1, kDebugSound, "CDROM: Playing track \"%s\"", trackName); - if ((_vm->getGameType() == kGameTypeFascination) && !scumm_stricmp(trackName, "boscle")) { + +// WORKAROUND - In Fascination CD, in the storage room, a track has the wrong +// name in the scripts, and therefore doesn't play. This fixes the problem. + if ((_vm->getGameType() == kGameTypeFascination) && !scumm_stricmp(trackName, "boscle")) _cdrom->startTrack("bosscle"); - } else + else _cdrom->startTrack(trackName); } -- cgit v1.2.3