void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right, int16 bottom, const char *str, int16 fontIndex, int16 color) { adjustCoords(1, &left, &top); adjustCoords(1, &right, &bottom); uint16 centerOffset = _vm->_game->_script->getFunctionOffset(TOTFile::kFunctionCenter); if (centerOffset != 0) { _vm->_game->_script->call(centerOffset); WRITE_VAR(17, (uint32) id); WRITE_VAR(18, (uint32) left); WRITE_VAR(19, (uint32) top); WRITE_VAR(20, (uint32) (right - left + 1)); WRITE_VAR(21, (uint32) (bottom - top + 1)); _vm->_inter->funcBlock(0); _vm->_game->_script->pop(); } if (str[0] == '\0') return; if (fontIndex >= kFontCount) { warning("Draw::printTextCentered(): Font %d > Count %d", fontIndex, kFontCount); return; } if (!_fonts[fontIndex]) return; _transparency = 1; _destSpriteX = left; _destSpriteY = top; _fontIndex = fontIndex; _frontColor = color; _textToPrint = str; Font &font = *_fonts[fontIndex]; int16 width = 0; if (!font.isMonospaced()) { const char *s = str; while (*s != '\0') width += font.getCharWidth(*s++); } else width = strlen(str) * font.getCharWidth(); adjustCoords(1, &width, 0); _destSpriteX += (right - left + 1 - width) / 2; spriteOperation(DRAW_PRINTTEXT); }
/** * @brief Update the last element in the linked list (the one at the lowest * level of nested Universes) to have the same coordinates as a * given point. * @param point a pointer to a point of interest */ void LocalCoords::updateMostLocal(Point* point) { /* Get the lowest level coordinate */ LocalCoords* curr = getLowestLevel(); /* Translate coordinates by appropriate amount */ double delta_x = point->getX() - curr->getX(); double delta_y = point->getY() - curr->getY(); adjustCoords(delta_x, delta_y); return; }
void Draw_Playtoons::spriteOperation(int16 operation) { int16 len; int16 x, y; SurfacePtr sourceSurf, destSurf; bool deltaVeto; int16 left; int16 ratio; Resource *resource; deltaVeto = (operation & 0x10) != 0; operation &= 0x0F; if (_sourceSurface >= 100) _sourceSurface -= 80; if (_destSurface >= 100) _destSurface -= 80; if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaVeto) { if ((_sourceSurface == kBackSurface) && (operation != DRAW_LOADSPRITE)) { _spriteLeft += _backDeltaX; _spriteTop += _backDeltaY; } if (_destSurface == kBackSurface) { _destSpriteX += _backDeltaX; _destSpriteY += _backDeltaY; if ((operation == DRAW_DRAWLINE) || ((operation >= DRAW_DRAWBAR) && (operation <= DRAW_FILLRECTABS))) { _spriteRight += _backDeltaX; _spriteBottom += _backDeltaY; } } } 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 == kFrontSurface) || (_destSurface == kBackSurface))) { 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_BLITSURF: case DRAW_DRAWLETTER: if (!sourceSurf || !destSurf) break; _spritesArray[_destSurface]->blit(*_spritesArray[_sourceSurface], _spriteLeft, spriteTop, _spriteLeft + _spriteRight - 1, _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_PUTPIXEL: switch (_pattern & 0xFF) { case 0xFF: warning("oPlaytoons_spriteOperation: operation DRAW_PUTPIXEL, pattern -1"); break; case 1: _spritesArray[_destSurface]->fillRect(destSpriteX, _destSpriteY, _destSpriteX + 1, _destSpriteY + 1, _frontColor); break; case 2: _spritesArray[_destSurface]->fillRect(destSpriteX - 1, _destSpriteY - 1, _destSpriteX + 1, _destSpriteY + 1, _frontColor); break; case 3: _spritesArray[_destSurface]->fillRect(destSpriteX - 1, _destSpriteY - 1, _destSpriteX + 2, _destSpriteY + 2, _frontColor); break; default: _spritesArray[_destSurface]->putPixel(_destSpriteX, _destSpriteY, _frontColor); break; } dirtiedRect(_destSurface, _destSpriteX - (_pattern / 2), _destSpriteY - (_pattern / 2), _destSpriteX + (_pattern + 1) / 2, _destSpriteY + (_pattern + 1) / 2); break; case DRAW_FILLRECT: switch (_pattern & 0xFF) { case 1: case 2: case 3: case 4: warning("oPlaytoons_spriteOperation: operation DRAW_FILLRECT, pattern %d", _pattern & 0xFF); break; case 0: _spritesArray[_destSurface]->fillRect(destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; default: warning("oPlaytoons_spriteOperation: operation DRAW_FILLRECT, unexpected pattern %d", _pattern & 0xFF); break; } break; case DRAW_DRAWLINE: if ((_needAdjust != 2) && (_needAdjust < 10)) { warning ("oPlaytoons_spriteOperation: operation DRAW_DRAWLINE, draw multiple lines"); _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); _spritesArray[_destSurface]->drawLine(_destSpriteX + 1, _destSpriteY, _spriteRight + 1, _spriteBottom, _frontColor); _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY + 1, _spriteRight, _spriteBottom + 1, _frontColor); _spritesArray[_destSurface]->drawLine(_destSpriteX + 1, _destSpriteY + 1, _spriteRight + 1, _spriteBottom + 1, _frontColor); } else { switch (_pattern & 0xFF) { case 0: _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); break; default: warning("oPlaytoons_spriteOperation: operation DRAW_DRAWLINE, draw %d lines", (_pattern & 0xFF) * (_pattern & 0xFF)); for (int16 i = 0; i <= _pattern; i++) for (int16 j = 0; j <= _pattern; j++) _spritesArray[_destSurface]->drawLine( _destSpriteX - (_pattern / 2) + i, _destSpriteY - (_pattern / 2) + j, _spriteRight - (_pattern / 2) + i, _spriteBottom - (_pattern / 2) + j, _frontColor); break; } } dirtiedRect(_destSurface, MIN(_destSpriteX, _spriteRight) - _pattern, MIN(_destSpriteY, _spriteBottom) - _pattern, MAX(_destSpriteX, _spriteRight) + _pattern + 1, MAX(_destSpriteY, _spriteBottom) + _pattern + 1); break; case DRAW_INVALIDATE: if ((_pattern & 0xFF) != 0) warning("oPlaytoons_spriteOperation: operation DRAW_INVALIDATE, pattern %d", _pattern & 0xFF); _spritesArray[_destSurface]->drawCircle(_destSpriteX, _destSpriteY, _spriteRight, _frontColor); dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, _destSpriteX + _spriteRight, _destSpriteY + _spriteBottom); break; case DRAW_LOADSPRITE: resource = _vm->_game->_resources->getResource((uint16) _spriteLeft, &_spriteRight, &_spriteBottom); if (!resource) 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; break; case DRAW_PRINTTEXT: len = strlen(_textToPrint); left = _destSpriteX; if ((_fontIndex >= 4) || (_fontToSprite[_fontIndex].sprite == -1)) { Font *font = _fonts[_fontIndex]; if (!font) { warning("oPlaytoons_spriteOperation: Trying to print \"%s\" with undefined font %d", _textToPrint, _fontIndex); break; } 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) { font->drawLetter(*_spritesArray[_destSurface], READ_LE_UINT16(dataBuf), _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); } } else { font->drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency, *_spritesArray[_destSurface]); _destSpriteX += len * font->getCharWidth(); } } else { for (int i = 0; i < len; i++) { font->drawLetter(*_spritesArray[_destSurface], _textToPrint[i], _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); _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; _spritesArray[_destSurface]->blit(*_spritesArray[_fontToSprite[_fontIndex].sprite], x, y, x + _fontToSprite[_fontIndex].width - 1, y + _fontToSprite[_fontIndex].height - 1, _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); _destSpriteX += _fontToSprite[_fontIndex].width; } } dirtiedRect(_destSurface, left, _destSpriteY, _destSpriteX - 1, _destSpriteY + _fonts[_fontIndex]->getCharHeight() - 1); break; case DRAW_DRAWBAR: if ((_needAdjust != 2) && (_needAdjust < 10)){ _spritesArray[_destSurface]->fillRect(_destSpriteX, _spriteBottom - 1, _spriteRight, _spriteBottom, _frontColor); _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _destSpriteX + 1, _spriteBottom, _frontColor); _spritesArray[_destSurface]->fillRect(_spriteRight - 1, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _destSpriteY + 1, _frontColor); } else { _spritesArray[_destSurface]->drawLine(_destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); _spritesArray[_destSurface]->drawLine(_spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); } dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_CLEARRECT: warning ("oPlaytoons_spriteOperation: DRAW_CLEARRECT uses _backColor %d", _backColor); if (_backColor != -1) { _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); } dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_FILLRECTABS: _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; default: warning ("oPlaytoons_spriteOperation: Unhandled operation %d", operation); 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) && !deltaVeto) { if (_sourceSurface == kBackSurface) { _spriteLeft -= _backDeltaX; _spriteTop -= _backDeltaY; } if (_destSurface == kBackSurface) { _destSpriteX -= _backDeltaX; _destSpriteY -= _backDeltaY; } } }
void Draw::oPlaytoons_sub_F_1B(uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *paramStr, int16 fontIndex, int16 var4, int16 shortId) { int16 width; char tmpStr[128]; strcpy(tmpStr, paramStr); adjustCoords(1, &left, &top); adjustCoords(1, &right, &bottom); uint16 centerOffset = _vm->_game->_script->getFunctionOffset(TOTFile::kFunctionCenter); if (centerOffset != 0) { _vm->_game->_script->call(centerOffset); WRITE_VAR(17, (uint32) id & 0x7FFF); WRITE_VAR(18, (uint32) left); WRITE_VAR(19, (uint32) top); WRITE_VAR(20, (uint32) (right - left + 1)); WRITE_VAR(21, (uint32) (bottom - top + 1)); if (_vm->_game->_script->peekUint16(41) >= '4') { WRITE_VAR(22, (uint32) fontIndex); WRITE_VAR(23, (uint32) var4); if (id & 0x8000) WRITE_VAR(24, (uint32) 1); else WRITE_VAR(24, (uint32) 0); WRITE_VAR(25, (uint32) shortId); if (_hotspotText) Common::strlcpy(_hotspotText, paramStr, 40); } _vm->_inter->funcBlock(0); _vm->_game->_script->pop(); } strcpy(paramStr, tmpStr); if (fontIndex >= kFontCount) { warning("Draw::oPlaytoons_sub_F_1B(): Font %d > Count %d", fontIndex, kFontCount); return; } if (!_fonts[fontIndex]) return; if (*paramStr) { _transparency = 1; _fontIndex = fontIndex; _frontColor = var4; if (_vm->_game->_script->peekUint16(41) >= '4' && strchr(paramStr, 92)) { char str[80]; char *str2; int16 strLen= 0; int16 offY, deltaY; str2 = paramStr; do { strLen++; str2++; str2 = strchr(str2, 92); } while (str2); deltaY = (bottom - right + 1 - (strLen * _fonts[fontIndex]->getCharHeight())) / (strLen + 1); offY = right + deltaY; for (int i = 0; paramStr[i]; i++) { int j = 0; while (paramStr[i] && paramStr[i] != 92) str[j++] = paramStr[i++]; str[j] = 0; _destSpriteX = left; _destSpriteY = offY; _textToPrint = str; width = stringLength(str, fontIndex); adjustCoords(1, &width, NULL); _destSpriteX += (top - left + 1 - width) / 2; spriteOperation(DRAW_PRINTTEXT); offY += deltaY + _fonts[fontIndex]->getCharHeight(); } } else { _destSpriteX = left; if (_vm->_game->_script->peekUint16(41) >= '4') _destSpriteY = right + (bottom - right + 1 - _fonts[fontIndex]->getCharHeight()) / 2; else _destSpriteY = right; _textToPrint = paramStr; width = stringLength(paramStr, fontIndex); adjustCoords(1, &width, NULL); _destSpriteX += (top - left + 1 - width) / 2; spriteOperation(DRAW_PRINTTEXT); } } return; }