void Animation::loadFrame(int frameNumber) { Scene &scene = _vm->_game->_scene; if (_skipLoad) return; Common::Point pt; int spriteListIndex = _spriteListIndexes[_header._spritesIndex]; SpriteAsset &spriteSet = *scene._sprites[spriteListIndex]; if (_unkIndex < 0) { MSurface *frame = spriteSet.getFrame(0); pt.x = frame->getBounds().left; pt.y = frame->getBounds().top; } else { pt.x = _unkList[_unkIndex].x; pt.y = _unkList[_unkIndex].y; _unkIndex = 1 - _unkIndex; } if (drawFrame(spriteSet, pt, frameNumber)) error("drawFrame failure"); }
void UISlots::draw(bool updateFlag, bool delFlag) { Scene &scene = _vm->_game->_scene; UserInterface &userInterface = scene._userInterface; DirtyArea *dirtyAreaPtr = nullptr; // Loop through setting up the dirty areas for (uint idx = 0; idx < size(); ++idx) { DirtyArea &dirtyArea = userInterface._dirtyAreas[idx]; UISlot &slot = (*this)[idx]; if (slot._flags >= IMG_STATIC) { dirtyArea._active = false; } else { dirtyArea.setUISlot(&slot); dirtyArea._textActive = true; if (slot._segmentId == IMG_SPINNING_OBJECT && slot._flags == IMG_FULL_UPDATE) { dirtyArea._active = false; dirtyAreaPtr = &dirtyArea; } } } userInterface._dirtyAreas.merge(1, userInterface._uiSlots.size()); if (dirtyAreaPtr) dirtyAreaPtr->_active = true; // Copy parts of the user interface background that need to be erased for (uint idx = 0; idx < size(); ++idx) { DirtyArea &dirtyArea = userInterface._dirtyAreas[idx]; UISlot &slot = (*this)[idx]; if (dirtyArea._active && dirtyArea._bounds.width() > 0 && dirtyArea._bounds.height() > 0 && slot._flags > -20) { if (slot._flags >= IMG_ERASE) { // Merge area userInterface.mergeFrom(&userInterface._surface, dirtyArea._bounds, Common::Point(dirtyArea._bounds.left, dirtyArea._bounds.top)); } else { // Copy area userInterface._surface.copyTo(&userInterface, dirtyArea._bounds, Common::Point(dirtyArea._bounds.left, dirtyArea._bounds.top)); } } } for (uint idx = 0; idx < size(); ++idx) { DirtyArea &dirtyArea = userInterface._dirtyAreas[idx]; UISlot &slot = (*this)[idx]; int slotType = slot._flags; if (slotType >= IMG_STATIC) { dirtyArea.setUISlot(&slot); if (!updateFlag) slotType &= ~0x40; dirtyArea._textActive = slotType > 0; slot._flags &= 0x40; } } userInterface._dirtyAreas.merge(1, userInterface._uiSlots.size()); for (uint idx = 0; idx < size(); ++idx) { DirtyArea *dirtyArea = &userInterface._dirtyAreas[idx]; UISlot &slot = (*this)[idx]; if (slot._flags >= IMG_STATIC && !(slot._flags & 0x40)) { if (!dirtyArea->_active) { do { dirtyArea = dirtyArea->_mergedArea; } while (!dirtyArea->_active); } if (dirtyArea->_textActive) { SpriteAsset *asset = scene._sprites[slot._spritesIndex]; // Get the frame details int frameNumber = ABS(slot._frameNumber); bool flipped = slot._frameNumber < 0; if (slot._segmentId == IMG_SPINNING_OBJECT) { MSprite *sprite = asset->getFrame(frameNumber - 1); sprite->copyTo(&userInterface, slot._position, sprite->getTransparencyIndex()); } else { MSprite *sprite = asset->getFrame(frameNumber - 1); if (flipped) { MSurface *spr = sprite->flipHorizontal(); userInterface.mergeFrom(spr, spr->getBounds(), slot._position, sprite->getTransparencyIndex()); delete spr; } else { userInterface.mergeFrom(sprite, sprite->getBounds(), slot._position, sprite->getTransparencyIndex()); } } } } } // Mark areas of the screen surface for updating if (updateFlag) { for (uint idx = 0; idx < size(); ++idx) { DirtyArea &dirtyArea = userInterface._dirtyAreas[idx]; if (dirtyArea._active && dirtyArea._textActive && dirtyArea._bounds.width() > 0 && dirtyArea._bounds.height() > 0) { // Flag area of screen as needing update Common::Rect r = dirtyArea._bounds; r.translate(0, scene._interfaceY); _vm->_screen.copyRectToScreen(r); } } } // Post-processing to remove slots no longer needed for (int idx = (int)size() - 1; idx >= 0; --idx) { UISlot &slot = (*this)[idx]; if (slot._flags < IMG_STATIC) { if (delFlag || updateFlag) remove_at(idx); else if (slot._flags > -20) slot._flags -= 20; } else { if (updateFlag) slot._flags &= ~0x40; else slot._flags |= 0x40; } } }