void GraphicsObjectData::render(const GraphicsObject& go, std::ostream* tree) { boost::shared_ptr<const Surface> surface = currentSurface(go); if (surface) { Rect src = srcRect(go); Rect dst = dstRect(go); int alpha = getRenderingAlpha(go); // TODO: Anyone attempting moving the clip area calculations here should // verify that it doesn't break the final pan scene of Yumemi in // Planetarian. if (tree) { objectInfo(*tree); *tree << " Rendering " << src << " to " << dst; if (alpha != 255) *tree << " (alpha=" << alpha << ")"; if (go.hasClip()) *tree << " [Warning: Clip rectangle calculations not applied.]"; *tree << endl; } surface->renderToScreenAsObject(go, src, dst, alpha); } }
void GraphicsObjectData::render(const GraphicsObject& go, const GraphicsObject* parent, std::ostream* tree) { boost::shared_ptr<const Surface> surface = currentSurface(go); if (surface) { Rect src = srcRect(go); Rect dst = dstRect(go, parent); int alpha = getRenderingAlpha(go, parent); if (go.buttonUsingOverides()) { // Tacked on side channel that lets a ButtonObjectSelectLongOperation // tweak the x/y coordinates of dst. There isn't really a better place to // put this. It can't go in dstRect() because the LongOperation also // consults the data from dstRect(). dst = Rect(dst.origin() + Size(go.buttonXOffsetOverride(), go.buttonYOffsetOverride()), dst.size()); } if (tree) { objectInfo(*tree); *tree << " Rendering " << src << " to " << dst << endl; if (parent) { *tree << " Parent: "; PrintGraphicsObjectToTree(*parent, tree); *tree << endl; } *tree << " Properties: "; if (alpha != 255) *tree << "(alpha=" << alpha << ") "; PrintGraphicsObjectToTree(go, tree); *tree << endl; } if (parent && parent->hasOwnClip()) { // In Little Busters, a parent clip rect is used to clip text scrolling // in the battle system. rlvm has the concept of parent objects badly // hacked in, and that means we can't directly apply the own clip // rect. Instead we have to calculate this in terms of the screen // coordinates and then apply that as a global clip rect. Point parent_start(parent->x() + parent->xAdjustmentSum(), parent->y() + parent->yAdjustmentSum()); Rect full_parent_clip = Rect(parent_start + parent->ownClipRect().origin(), parent->ownClipRect().size()); Rect clipped_dest = dst.intersection(full_parent_clip); Rect inset = dst.getInsetRectangle(clipped_dest); dst = clipped_dest; src = src.applyInset(inset); if (tree) { *tree << " Parent Own Clipping Rect: " << parent->ownClipRect() << endl << " After clipping: " << src << " to " << dst << endl; } } if (go.hasOwnClip()) { dst = dst.applyInset(go.ownClipRect()); src = src.applyInset(go.ownClipRect()); if (tree) { *tree << " Internal Clipping Rect: " << go.ownClipRect() << endl << " After internal clipping: " << src << " to " << dst << endl; } } // Perform the object clipping. if (go.hasClip()) { Rect clipped_dest = dst.intersection(go.clipRect()); // Do nothing if object falls wholly outside clip area if (clipped_dest.isEmpty()) return; // Adjust the source rectangle Rect inset = dst.getInsetRectangle(clipped_dest); dst = clipped_dest; src = src.applyInset(inset); if (tree) { *tree << " Clipping Rect: " << go.clipRect() << endl << " After clipping: " << src << " to " << dst << endl; } } // TODO: Do we want to skip this if no alpha? surface->renderToScreenAsObject(go, src, dst, alpha); } }